获取抛出信号的线程的id

Ale*_*xis 2 c c++ multithreading signals c++11

我想知道是否有一种简单的方法可以在不使用中间信号 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();
}
Run Code Online (Sandbox Code Playgroud)

所以我得到了

Begin thread 1Begin thread 2
Thread 1 have received the signal: 11
Caught the signal:11
end thread1
end thread2
Run Code Online (Sandbox Code Playgroud)

但是如果我有 5 个线程,我可以避免创建 5 个处理程序吗?

编辑我的包含内容是

#include <thread>
#include <chrono>
#include <iostream>
#include <csignal>
Run Code Online (Sandbox Code Playgroud)

编辑 我想我正在寻找类似我发现的东西/sf/answers/1138152711/ 但由于这个东西还不存在,我必须找到其他东西

Chr*_*ine 5

你的问题的答案是“否”。您可以控制软件中断异步执行的线程(通过阻塞特定线程中的信号);在 POSIX 平台上,您可以阻止所有线程中信号的异步执行,而是使用 sigwait() 在专用线程中响应信号。但是,如果中断是通过调用 Kill() 发生的,或者是系统生成的中断(例如 SIGSEGV),则 POSIX 中没有标准方法来确定信号处理程序中哪个线程生成了信号。

请注意,线程不会“抛出”信号。另请注意,这些都与 C++ 标准无关。

编辑我注意到您的评论者之一可能会假设信号处理程序在生成信号的线程中执行。除了调用 raise() 的情况外,情况并非如此。由kill() 产生的信号或系统生成的信号可以在任何未阻止该信号的线程中异步执行。如果多个线程的信号被解除阻塞,那么哪个线程被中断是不确定的(这是系统及其调度程序的选择)。另请注意,如果中断是用户生成的,则在 POSIX 中可以调用 sigqueue() 而不是 kill(),并且 sigqueue 可以传入用户数据值,该数据值可以识别调用者的身份。但这显然与 SIGSEGV 无关。在 POSIX 中,使用 pthread_kill() 还可以导致信号中断调用进程中的特定线程(但这不会识别调用者,也与 SIGSEGV 无关)。多线程程序中的 raise() 与调用 pthread_kill() 一样有效(它将在调用 raise() 的线程中执行:但 raise() 对于信息传递目的来说是无用的)。