在哪些情况下可以在 non-main 线程中执行信号处理程序?
In which situations a signal handler can be executed in the non-main thread?
我的问题正是标题所说的(仅针对 Unix/Linux)。我假设用户对 std::raise
和 std::abort
的调用总是在发出调用的同一个线程中执行,但是,我对发送信号的异步和内核例程有一些疑问...
- 如果我从命令行向线程 pid 发送信号,线程会处理该信号还是由主线程处理,具体取决于已发送的信号?
- 如果
malloc
检测到一些堆损坏,信号会被发送到主线程还是会在调用 malloc
的线程中执行?同样的问题适用于生成 SIGFPE 或 SIGSEGV 的错误。
- 有些信号总是由主线程处理,无论是哪个线程引起的,或者是发送到哪个 pid 的?
- 在多线程上下文中还有哪些其他情况值得一提?
main()
线程并不特殊。它像任何其他线程一样接收信号。
当为进程或进程组生成信号 "asynchronously" 时(例如,通过 kill
或终端上的 Ctrl-C),实现可以选择任何线程进行传递。
执行main()
的线程与进程中的任何其他线程没有区别。如果你想控制哪个线程接收信号,你必须在除一个线程之外的所有线程中阻止信号传递,或者阻止并从你想要的线程调用 sigwait
。
当信号在线程内生成 "synchronously"(如 raise
、abort
、分段错误等)或针对特定线程(如pthread_kill
),那么那个线程,而且只有那个线程,会得到信号。如果该线程正在阻塞信号,则信号将保持挂起状态,直到解除阻塞或被接受。
这里有两个非常好的来源是全面但相对密集的 UNIX 信号 POSIX treatment and the pleasantly accessible GNU libc treatment。但是,两者都面向 C 而不是 C++。
我的问题正是标题所说的(仅针对 Unix/Linux)。我假设用户对 std::raise
和 std::abort
的调用总是在发出调用的同一个线程中执行,但是,我对发送信号的异步和内核例程有一些疑问...
- 如果我从命令行向线程 pid 发送信号,线程会处理该信号还是由主线程处理,具体取决于已发送的信号?
- 如果
malloc
检测到一些堆损坏,信号会被发送到主线程还是会在调用malloc
的线程中执行?同样的问题适用于生成 SIGFPE 或 SIGSEGV 的错误。 - 有些信号总是由主线程处理,无论是哪个线程引起的,或者是发送到哪个 pid 的?
- 在多线程上下文中还有哪些其他情况值得一提?
main()
线程并不特殊。它像任何其他线程一样接收信号。
当为进程或进程组生成信号 "asynchronously" 时(例如,通过 kill
或终端上的 Ctrl-C),实现可以选择任何线程进行传递。
执行main()
的线程与进程中的任何其他线程没有区别。如果你想控制哪个线程接收信号,你必须在除一个线程之外的所有线程中阻止信号传递,或者阻止并从你想要的线程调用 sigwait
。
当信号在线程内生成 "synchronously"(如 raise
、abort
、分段错误等)或针对特定线程(如pthread_kill
),那么那个线程,而且只有那个线程,会得到信号。如果该线程正在阻塞信号,则信号将保持挂起状态,直到解除阻塞或被接受。
这里有两个非常好的来源是全面但相对密集的 UNIX 信号 POSIX treatment and the pleasantly accessible GNU libc treatment。但是,两者都面向 C 而不是 C++。