最近项目里大量用到了多线程,出了一些问题,经过一番研究后找到了问题所在,同时对多线程理解更深了一步,故写此博客分享一波。。。

将我遇到的问题简化为一下代码,示例:

#include <iostream>
#include <thread>

int main()
{
    std::thread t([]() {
        std::string s = "123";
        std::thread tt([&]() {
            std::cout << s << std::endl;
        });
        tt.detach();
    });
    t.detach();

    std::cin.get();
    return 0;
}

上面的代码执行错误,报 “引发了异常:读取访问权限冲突”。这是因为s已经析构了。对一个已经析构的对象进行操作,必然会出现问题。

程序执行到tt.detach()后会继续向下执行,然后会遇到 } ,会调用对象的析构函数。

解决方法:

1. tt.detach()换成tt.join(), join()会阻塞在那里,等待线程函数执行完。

2. 将捕获引用改为捕获值   [&]  改为 [=] 或者 [s]。

话说的这么简单,但是在一个项目里线程套线程,中间又可能夹杂着大量的代码,难免会忘记一些东西,所以我总结如下:

如果想用detach,则lambda表达式 的捕获列表应该尽量用值传递,或者用引用传递进来,拷贝一份用拷贝的值,总之不要用外面的值,(多此一举,直接捕获值多好)。

如果用join,则没有这么多的顾虑。。。

0

Publication author

offline 2年

lengyuewuxin

0
Comments: 0Publics: 25Registration: 15-07-2018
Authorization
*
*
Registration
*
*
*
Password generation