2013-07-24 19 views
2

我想知道是否有趕線程誰墜毀的id一種簡單的方法,而無需使用中間體signal_handlers獲取誰扔的信號

線程的id我有以下代碼

void signal_handler(int signal) 
{ 
    std::cout << "Caught the signal:" << signal << std::endl; 
} 

void handler_t1(int signal) 
{ 
    std::signal(SIGSEGV, signal_handler); 
    std::cout << "Thread 1 have received the signal: " << signal << std::endl; 
    std::raise(SIGSEGV); 
} 

void f1() 
{ 
    std::signal(SIGSEGV, handler_t1); 
    std::cout << "Begin thread 1" << std::endl; 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
    std::raise(SIGSEGV); 
    std::cout << "end thread1" << std::endl; 
} 

void f2() 
{ 
    std::cout << "Begin thread 2" << std::endl; 
    std::this_thread::sleep_for(std::chrono::seconds(3)); 
    std::cout << "end thread2" << std::endl; 
} 

int  main() 
{ 
    std::thread t1(f1); 
    std::thread t2(f2); 

    t1.join(); 
    t2.join(); 
} 

所以我得到的

Begin thread 1Begin thread 2 
Thread 1 have received the signal: 11 
Caught the signal:11 
end thread1 
end thread2 

但是,如果我有5個線程,我能避免創建5處理器?

編輯我是包括

#include <thread> 
#include <chrono> 
#include <iostream> 
#include <csignal> 

編輯 我覺得我一直在尋找類似的東西,我發現https://stackoverflow.com/a/16259324/2380470 但因爲這件事不存在,我一定要找到的東西否則

+0

一般而言,信號不會從您自己的線程中拋出,所以我不確定這是否合理。如果它來自'kill -s SIGSEGV '? – BoBTFish

+0

@Alexis您會介意在代碼中發佈適當的包含嗎?我可能會對你的問題的某些部分感興趣。 – hetepeperfan

+0

@hetepeperfan包括我發現在std網站(編輯我的問題) – Alexis

回答

4

您的問題的答案是「否」。您可以控制軟件中斷異步執行的線程(通過在特定線程中阻塞信號);並且在POSIX平臺上,您可以阻止所有線程中信號的異步執行,而是使用sigwait()在專用線程中響應信號。但是,如果中斷是通過調用kill()來實現的,或者是系統生成的中斷(如SIGSEGV),POSIX中沒有標準的方式來確定信號處理程序中哪個線程生成了信號。

請注意,線程不會「拋出」信號。還要注意,這與C++標準沒有關係。

編輯我注意到您的一個評論者可能會認爲信號處理程序在生成信號的線程中執行。除了要求raise()的情況外,情況並非如此。從kill()或系統生成的信號可以在任何線程沒有阻塞該信號的情況下異步執行。如果不止一個線程的信號未被阻塞,則不確定哪個線程被中斷(這是系統及其調度器的選擇)。還要注意的是,在用戶生成中斷的情況下,在POSIX中,可以調用sigqueue()而不是kill(),並且sigqueue可以傳遞用戶數據值,該值可以標識調用者的身份。但是,這顯然與SIGSEGV無關。在POSIX中,使用pthread_kill()還可以使信號中斷調用進程中的特定線程(但不能識別調用者,也不與SIGSEGV相關)。在多線程程序中raise()對pthread_kill()有調用作用(它會在調用raise()的線程中執行:但raise()對於傳遞信息是沒有用的)。

2

gettid()會給你調用它的線程的id。這會給你你想要的!

http://linux.die.net/man/2/gettid

如果您存儲在線程一些線程緩衝排序也一樣,你總是可以只標示他們自己基於他們位於陣列(如螺紋,其中0 - > N代表線程[ n])

+0

這隻有在每個線程都有處理程序時纔有效,他特別說他希望避免這種處理程序。 – BoBTFish

+1

信號處理程序由整個過程共享。你總是在每個線程上有一個處理程序(同一個),或者根本沒有處理程序。 –

+0

是的,他只需要捕捉他尋找的異常,然後在處理程序 – Magn3s1um