C++核心准则:CP.25: gsl::joining_thread好于std::thread

CP.25: Prefer gsl::joining_thread over std::thread

CP.25: gsl::joining_thread好于std::thread

 

Reason(原因)

A joining_thread is a thread that joins at the end of its scope. Detached threads are hard to monitor. It is harder to ensure absence of errors in detached threads (and potentially detached threads).

joining_thread是一种在和作用域连结的线程。分离之后的线程很难监控。很难保证分离之后(或者存在潜在的分离可能性)的线程中不存在错误。

 

Example, bad(反面示例)

void f() { std::cout << "Hello "; }

struct F {
    void operator()() const { std::cout << "parallel world "; }
};

int main()
{
    std::thread t1{f};      // f() executes in separate thread
    std::thread t2{F()};    // F()() executes in separate thread
}  // spot the bugs

Example(示例)

void f() { std::cout << "Hello "; }

struct F {
    void operator()() const { std::cout << "parallel world "; }
};

int main()
{
    std::thread t1{f};      // f() executes in separate thread
    std::thread t2{F()};    // F()() executes in separate thread

    t1.join();
    t2.join();
}  // one bad bug left

Note(注意)

Make "immortal threads" globals, put them in an enclosing scope, or put them on the free store rather than detach(). Don't detach.

将“永远有效的线程"定义为全局的,将它们限制在一个封闭的作用域,或者将它们放在自由存储中而不是分离它们。不要分离线程。

 

Note(注意)

Because of old code and third party libraries using std::thread, this rule can be hard to introduce.

因为旧代码和第三方库在使用std::thread,本准则很难推广。

 

Enforcement(实施建议)

Flag uses of std::thread:

标记使用std::thread的代码:

  • Suggest use of gsl::joining_thread or C++20 std::jthread.

  • 建议使用gsl::joining_thread或者C++20引入的std::jthread.

  • Suggest "exporting ownership" to an enclosing scope if it detaches.

  • 如果需要分离线程,建议“输出所有权”到封闭的作用域。

  • Warn if it is not obvious whether a thread joins or detaches.

  • 如果不好判断线程会连结还是分离,报警。

 

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp25-prefer-gsljoining_thread-over-stdthread

 


 

新书介绍

以下是本人3月份出版的新书,拜托多多关注!

 

本书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。

对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。

 

觉得本文有帮助?欢迎点赞并分享给更多的人。

阅读更多更新文章,请关注微信公众号【面向对象思考】

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联三个进度条类型的变量;并在对话框的初始化函数中,设定进度条的范围;为编辑框关联一个整型的变量;为12个按钮添加消息处理函数; 2. 定义结构体:用做线程函数的参数传递 typedef struct Threadinfo{ CProgressCtrl *progress;//进度条对象 int speed; //进度条速度 int pos; //进度条位置 } thread,*lpthread; 3. 为对话框增加三个句柄,用于标识各个线程; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1.progress=&m_progress1;//进度条对象 thread1.speed=100;//速度 thread1.pos=0;//初始位置 hThread1=CreateThread(NULL,0,ThreadFun,&thread1;,0,0);//创建并开始线程 if (!hThread1) { MessageBox("创建线程失败"); } 7. 编写线程函数(一般是一个死循环,或者需要花费时间很长的算法!否者就失去了多线程的意义) DWORD WINAPI ThreadFun(LPVOID pthread) //线程入口函数 { lpthread temp=(lpthread)pthread;//参数强制转换为结构体类型 temp->progress->SetPos(temp->pos); //设置被传递过来的进度条的位置 while(temp->posspeed); /设置速度 temp->pos++; //增加进度 temp->progress->SetPos(temp->pos); //设置进度条的新位置 GlobalVar--; if(temp->pos==20) { temp->pos=0; //进度条满则归0 } } return true; } 8. 在挂起按钮函数中,编写如下代码: if(SuspendThread(hThread1)==0xFFFFFFFF) { MessageBox("挂起失败!进程可能已经死亡或未创建!"); return; } 9. 在执行按钮函数中,编写如下代码: if(ResumeThread(hThread1)==0xFFFFFFFF) { MessageBox("执行失败!进程可能已经死亡或未创建!"); return; } 10. 在停止按钮函数中,编写如下代码: if(TerminateThread(hThread1,0))//前些终止线程 { CloseHandle(hThread1);//销毁线程句柄 } else { MessageBox("终止进程失败!"); } 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值