c++ thread 使用不当导致的崩溃问题

看个例子

 1 class CTimer{
 2 public:
 3     // 析构函数
 4     virtual ~CTimer(){
 5  
 6     }
 7     // 开始
 8     void start()
 9     {
10         b_exit = false;
11         i = 10;
12         t = new std::thread(&CTimer::run, this);
13     }
14  
15     void run()
16     {
17 //         Sleep(1000);
18 //         i = 800;
19         stop();
20         return;
21     }
22  
23     // 结束
24     void stop()
25     {
26         int lll = i;
27         b_exit = true;
28         if (t->joinable())
29         {
30             t->join();
31         }
32     }
33 private:
34     std::thread *t;
35     std::thread *t1;
36     int i;
37     bool b_exit;
38 };
39 void main(){
40     CTimer time_test;
41     time_test.start();
42     //time_test.stop();
43     system("pause");
44 }

如图所示,程序会崩溃,分析了是因为两个线程都在编辑变量t,子线程调用t时主线程不一定赋值已经完成,就会造成空指针的操作,加锁可避免这种问题

附一个别人遇到的问题

 1 ConsoleUploadFile::ConsoleUploadFile()
 2 {
 3    ... ...
 4    
 5     std::thread( &ConsoleUploadFile::uploadFile, this);
 6 }
 7  
 8  
 9  
10 很奇怪的是,代码运行到std::thread(...)这句就崩溃了,还没有跑子线程绑定的函数uploadFile,我开始怀疑不能在构造函数中开线程,就另写了一个成员函数,但也是运行到std::thread(..)就崩溃。google了一番,没有进展,只能靠调试了,崩溃的现场是这样的:
11  
12  
13 libc++.1.dylib`std::__1::thread::~thread():
14  
15 0x7fff8c2c9984:  pushq  %rbp
16  
17 0x7fff8c2c9985:  movq   %rsp, %rbp
18  
19 0x7fff8c2c9988:  cmpq   $0, (%rdi)
20  
21 0x7fff8c2c998c:  jne   0x7fff8c2c9990           ; std::__1::thread::~thread() +12
22  
23 0x7fff8c2c998e:  popq   %rbp
24  
25 0x7fff8c2c998f:  ret    
26  
27 0x7fff8c2c9990:  callq  0x7fff8c2ca4fc            ; symbol stub for: std::terminate()
28  
29 0x7fff8c2c9995:  nop    
30  
31  
32 仔细看一下,这里怎么会调用thread的析构函数呢?问题就出在这里,直接放一个光溜溜的构造函数,当然会被马上析构了...
33  
34 改成:
35  
36        _thread = std::thread( &ConsoleUploadFile::uploadFile, this);
37  
38 就可以了,_thread为成员变量。
39  
40  
41  
42 可是,程序退出的时候,又崩溃了,是在析构函数崩溃的
43  
44 ConsoleUploadFile::~ConsoleUploadFile()
45 {
46 }
47  
48 libc++.1.dylib`std::__1::thread::~thread():
49  
50 0x7fff8c2c9984:  pushq  %rbp
51  
52 0x7fff8c2c9985:  movq   %rsp, %rbp
53  
54 0x7fff8c2c9988:  cmpq   $0, (%rdi)
55  
56 0x7fff8c2c998c:  jne   0x7fff8c2c9990            ; std::__1::thread::~thread() +12
57  
58 0x7fff8c2c998e:  popq   %rbp
59  
60 0x7fff8c2c998f:  ret    
61  
62 0x7fff8c2c9990:  callq 0x7fff8c2ca4fc            ; symbol stub for: std::terminate()
63  
64 0x7fff8c2c9995:  nop    
65  
66 还是和子线程有关,看来是有什么资源没有释放,又是一顿查,原来需要call 一下join(),文档上是这么说的:
67  
68 After a call to this function, the thread object becomes non-joinable and can be destroyed safely.
69  
70  
71  
72 ConsoleUploadFile::~ConsoleUploadFile()
73 {
74     _thread.join();
75 }
76  

 

原文链接: https://www.cnblogs.com/wangshaowei/p/10744651.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    c++ thread 使用不当导致的崩溃问题

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/391590

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月31日 上午10:40
下一篇 2023年3月31日 上午10:40

相关推荐