2013-07-24 21 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