C++编程指南20-使用joining_thread以确保线程不会在变量生命周期之外运行
- 游戏开发
- 2025-09-17 14:21:03

一:概述
在多线程编程中,如果一个线程需要访问外部作用域的变量,就必须保证这个变量在 线程结束之前依然有效,否则可能会出现 悬空指针(dangling pointer) 的问题,导致 未定义行为。
二:如何解决?使用 joining_thread(类似 std::thread,但会在析构时自动 join(),且不能 detach())可以避免这种问题,因为:
线程的生命周期受到管理:不会意外地 detach() 导致资源泄漏。作用域内对象的生命周期受控:确保线程所访问的对象在其执行期间是有效的。 三:代码示例 #include <iostream> #include <thread> #include <memory> void f(int* p) { *p = 99; } int glob = 33; void some_fct(int* p) { int x = 77; std::thread t0(f, &x); // ✅ OK:x 在作用域内 std::thread t1(f, p); // ✅ OK:p 是外部传入的 std::thread t2(f, &glob); // ✅ OK:glob 是全局变量 auto q = std::make_unique<int>(99); std::thread t3(f, q.get()); // ❌ 错误!q 是局部变量,t3 可能在 q 析构后访问无效地址 t0.join(); t1.join(); t2.join(); t3.join(); }以上 t3(f, q.get()); 可能会导致 悬空指针,因为 q 在 some_fct() 结束时会被销毁,而 t3 可能仍然在运行,这样 f() 就可能访问已释放的内存,导致 未定义行为。
解决办法:使用 joining_thread(概念类似 std::thread,但会在析构时自动 join(),确保线程不会在变量生命周期之外运行)
#include <iostream> #include <thread> #include <memory> class joining_thread { std::thread t; public: template <typename... Args> explicit joining_thread(Args&&... args) : t(std::forward<Args>(args)...) {} ~joining_thread() { if (t.joinable()) { t.join(); } } joining_thread(const joining_thread&) = delete; joining_thread& operator=(const joining_thread&) = delete; }; void f(int* p) { *p = 99; } int glob = 33; void some_fct(int* p) { int x = 77; joining_thread t0(f, &x); // ✅ OK:x 在作用域内 joining_thread t1(f, p); // ✅ OK:p 是外部传入的 joining_thread t2(f, &glob); // ✅ OK:glob 是全局变量 auto q = std::make_unique<int>(99); joining_thread t3(f, q.get()); // ✅ OK:q 仍然在作用域内 // 这里不需要手动 join(),析构时会自动 join() }C++编程指南20-使用joining_thread以确保线程不会在变量生命周期之外运行由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C++编程指南20-使用joining_thread以确保线程不会在变量生命周期之外运行”
上一篇
关于博客系统的测试报告