c++11线程的使用坑点总结

本文总结了C++11线程使用中的一些常见问题,包括:线程的join与detach选择,线程对象生命周期管理,线程参数传递的规则,以及使用互斥量保护数据的注意事项。强调了在多线程编程中确保数据安全性的重要性。
摘要由CSDN通过智能技术生成
坑点总结

1、启动了线程,你需要明确是要等待线程结束(调用join),还是让其自主运行(调用detach)。如果std::thread对象销毁之前还没有做出决定,程序就会终止(std::thread的析构函数会调用std::terminate())。因此,即便是有异常存在,也需要确保线程能够正确的加入(joined)或分离(detached)。。需要注意的是,必须在std::thread对象销毁之前做出决定,否则你的程序将会终止(std::thread的析构函数会调用std::terminate(),这时再去决定会触发相应异常)。
如果不等待线程,就必须保证线程结束之前,可访问的数据的有效性。这不是一个新问题——单线程代码中,对象销毁之后再去访问,也会产生未定义行为——不过,线程的生命周期增加了这个问题发生的几率。
这种情况很可能发生在线程还没结束,函数已经退出的时候,这时线程函数还持有函数局部变量的指针或引用。下面的清单中就展示了这样的一种情况。

class func1
{
   
public:  
    func1(int &a) : i(a) {
   }
    void operator() ()
    {
      
        //在这里调用i变量
    }
private: 
    int &i;
};

void oops()
{
   
    int local_variable = 0;
    func1 my_func(local_variable);
    std::thread my_thread(my_func);
    my_thread.detach(); //这里将线程分离,可能local_vriable变量已经销毁该线程还在运行   
}
  • 这个例子中,已经决定不等待线程结束(使用了detach() ),所以当oops()函数执行完成时,新线程中的函数可能还在运行。如果线程还在运行,它就会访问已经销毁的变量。如同一个单线程程序——允许在函数完成后继续持有局部变量的指针或引用;当然,这从来就不是一个好主意——这种情况发生时,错误并不明显,且会使多线程更容易出错。
  • 处理这种情况的常规方法:使线程函数的功能齐全,将数据复制到线程中,而非复制到共享数据中。如果使用一个可调用的对象作为线程函数,这个对象就会复制到线程中,而后原始对象就会立即销毁。但对于对象中包含的指针和引用还需谨慎,
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值