假设我有一个线程 A,它想向线程 B、C 和 D 发送信号。我可以这样做吗?
SendSignalTo( ThreadB, SIGUSR1 );
SendSignalTo( ThreadC, SIGUSR1 );
SendSignalTo( ThreadD, SIGUSR1 );
对于 SIGUSR1 信号处理程序,线程 B、C 和 D 的定义不同,如下所示。
void SIGUSR1_Handler_for_ThreadB(...){...}
void SIGUSR1_Handler_for_ThreadC(...){...}
void SIGUSR1_Handler_for_ThreadD(...){...}
如果不能,还有什么选择。
最佳答案
您可以使用 pthread_kill()
向特定线程发送信号, 或者如果你不介意是特定于 GNU 的,使用 pthread_sigqueue()
(可以指定一个 int
或 void *
处理程序可以通过 info->si_value
访问)。
进程的每个信号只有一个信号处理程序。这意味着一个特定的信号将始终调用相同的处理函数,无论它恰好是哪个线程。如果一个线程设置了新的信号处理程序,则所有线程的信号处理程序都将更改。
但是,解决方法很简单:使用每线程函数指针来定义信号处理程序应该调用哪个函数。请记住信号处理程序的限制——您只能使用 async-signal safe functions在信号处理程序中。
/* Simplify by defining the signal handler function type, assume SA_SIGINFO */
typedef void (*signal_handler_t)(int, siginfo_t *, void *);
/* Per-thread variable pointing to the desired function */
static __thread signal_handler_t thread_handler = NULL;
/* Process-wide actual signal handler */
static void signal_handler(int signum, siginfo_t *info, void *context)
{
signal_handler_t func;
func = __sync_fetch_and_or(&thread_handler, (signal_handler_t)0);
if (func)
func(signum, info, context);
}
原子加载 (__sync_fetch_and_or()
) 允许您在任何时间点使用简单的原子存储轻松更改每线程处理程序,甚至不会阻塞信号。然后切换到函数 new_thread_handler
signal_handler_t func;
do {
func = thread_handler;
} while (!__sync_bool_compare_and_swap(&thread_handler, func, new_thread_handler));
__sync_fetch_and_or()
和函数开关都可以用一个 C++11 风格的 __atomic_
调用代替,但我没有足够新的 GCC但是,所以我仍在使用旧式 __sync_
调用。
POSIX 还支持实时 信号,SIGRTMIN+0
, SIGRTMIN+1
, .., SIGRTMAX
。它们还有一个额外的好处,即它们中的多个可以同时挂起。它们比传统信号更适合这种情况。
关于c++ - 我可以向不同的线程发送信号吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12820765/