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  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM