线程连接问题
Thread joining issue
我读了一些关于线程的手册,我觉得它们显示的代码不安全:
std::cout << "starting first helper...n";
std::thread helper1(foo);
std::cout << "starting second helper...n";
std::thread helper2(bar);
std::cout << "waiting for helpers to finish..." << std::endl;
helper1.join(); // #1 NOT SAFE
helper2.join(); // #2 NOT SAFE
我认为这个代码不是绝对安全的。如果我没有弄错的话,当控制到达标记为#1
和#2
的行时,不能保证helper1
和helper2
已经处于可连接状态。线程可能仍然无法启动,并且此时没有id。这将导致从std::thread::join()
引发未捕获的异常
我认为下面的代码解决了这个问题。我说得对吗?
std::cout << "starting first helper...n";
std::thread helper1(foo);
std::cout << "starting second helper...n";
std::thread helper2(bar);
std::cout << "waiting for helpers to finish..." << std::endl;
while ( helper1.joinable() == false ) { }
helper1.join(); // #1 SAFE
while ( helper2.joinable() == false ) { }
helper2.join(); // #2 SAFE
如果std::thread
包含未经join
编辑或detatch
编辑的线程状态,则CCD_6为joinable
。
std::thread
通过非默认构造或从另一个std::thread
将一个CCD11插入其中来获得线程状态。move
从发出时丢失。
在构造完成后,获得线程状态不会延迟。当线程函数结束时,它不会消失。所以没有这个问题。
有一个问题是,如果代码抛出以上内容,您将无法执行join
或detatch
,从而导致程序关闭时出现坏消息。为了避免这种情况,请始终将std::thread
包装在RAII包装中,或者只使用返回void
的std::async
,并以类似的方式包装生成的std::future
(因为标准规定它在dtor中阻塞,但微软的实现没有,所以你不能相信它是否会阻塞)。
您对线程的感知过于复杂。join
用于安全地加入线程。只需使用:
std::thread my_thread(my_main);
my_thread.join();
std::thread::thread(F&& f, Args&&... args)
构造函数具有以下后置条件:
后置条件:
get_id() != id()
。CCD_ 23表示新启动的线程。
joinable()
的定义是
返回:
get_id() != id()
因此,构造函数的后处理条件是对象是可联接的,并且在构造函数完成后立即应用后处理条件。操作系统是否真的启动了线程是无关紧要的,thread
对象仍然知道新线程的ID,并且仍然可以等待它完成并加入它。
- 到连接组件算法的问题(递归)
- 使用 bfs 解决连接组件问题时得到错误的答案
- CMake 错误"源似乎不包含 CMakeLists.txt",路径/库连接问题
- 连接 MATLAB 和 Visual Studios 的问题
- Cesanta Mongoose - 连接到本地主机时出现问题
- 通过 COM 对象连接 x64 应用程序时出现问题
- Qt的新信号/时隙语法问题 - 连接到一个简单的函数
- 无线局域网连接问题
- C++ Qt SQL lite 数据库连接问题
- 在 Windows 问题上连接到企业 WiFi
- 我的字符串类的 += 运算符有问题,它没有正确连接字符串
- 与Mingw(V.4.3.0)和Libhid连接的问题
- 尝试创建表面网格,但遇到连接问题
- Qt - 在课堂上连接 - 出了点问题 - 这个
- 连接GLUT和QGLViewer的问题
- 从使用 emscripten 编译的 c++ 连接 websocket 时出现问题
- 闲置期后的redis pubsub连接问题
- 使用WebSocketpp启用了Websocketpp接受连接的问题
- 在Visual Studio 2017中连接NLOPT-2.4.2的问题
- QT中的TCP连接性能低问题