2016-10-20 58 views
7

在下面的程序中,我創建了一個pthread_t thread1,它在函數func()中崩潰。我感興趣的是pthread_join命令在main()中發生了什麼。當子線程崩潰並且主要等待連接時會發生什麼?

我在程序下運行,並在正常退出時打印「完成」。我不知道爲什麼?

#include <iostream> 
#include <string> 
#include <vector> 
#include <map> 
#include <cstring> 
#include <climits> 
#include <cstdio> 
#include<pthread.h> 
#include <stdlib.h> 
using namespace std; 

void* func(void *data) 
{ 
    cout<<"Calling func"<<(long)(data)<<endl; 
    int *a; 
    cout<<a[2]<<endl; 
    pthread_exit(0); 
} 

int main() 
{ 
    pthread_t thread1; 
    pthread_create(&thread1, 0 , &func, (void*)2); 
    pthread_join(thread1, NULL); 
    cout<<"complete"<<endl; 

} 
+0

您調用了未定義的行爲。你是(非)幸運的程序繼續,似乎在宇宙中的一切都是正確的。因此UB的性質。 – WhozCraig

+0

@WhozCraig哪裏有「未定義」? – GhostCat

+1

@GhostCat取消引用一個不確定的指針。 – WhozCraig

回答

2

線程的操作大多是獨立的,這意味着每個線程都可以使用信號處理程序來捕獲「崩潰」信號,而不會讓其他線程被殺死。因此需要添加信號處理程序。

源:信號手冊頁http://man7.org/linux/man-pages/man7/signal.7.html

的信號可以產生(並且因此待處理),用於處理作爲一個整體 (例如,當使用kill發送(2))或用於一個特定的線程(例如 某些信號,例如SIGSEGV和SIGFPE,作爲執行特定機器語言指令的結果而產生,如針對使用 pthread_kill(3))的特定線程的信號。處理導向的信號可以被傳送到當前沒有信號被阻塞的線程中的任何一個線程。 如果不止一個線程的信號未被阻塞,那麼內核將選擇一個任意線程來傳送信號。

+1

只有當'SIGSEGV'安裝了一個處理程序,在這種情況下線程沒有「崩潰」 - 它才進入信號處理程序。如果線程真的崩潰了(沒有安裝信號處理程序),那麼整個進程就會被終止。 – caf

5

該過程本身會在您的情況下段錯誤。

如果您將NULL分配給a,您可以看到它會崩潰。在當前代碼中,您以非確定性方式調用a。一些隨機位置由a引用。因此行爲是不確定的。有時你會看到main中的日誌語句,其他時候程序將崩潰。如果程序在執行過程中崩潰,請考慮一下自己的幸運

如果線程執行NULL指針取消引用,它會將整個過程關閉。它是一個進程崩潰而不是線程崩潰。

+0

「如果你要給NULL分配一個你可以看到它肯定會崩潰」不,不是肯定的。這仍然是未定義的行爲。 – juanchopanza

+0

@jaunchopanza,同意。使用空指針參數進程崩潰的可能性遠遠大於非空參數。我將相應地編輯答案。 – Prabhu

+0

@Prabhu是的,整個程序崩潰的情況下NULL解引用所以,如果一個線程崩潰,然後整個進程craches。對? – EmptyData

相關問題