假设我有一个线程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(...){...}
如果没有,那么替代方案是什么。
答案 0 :(得分:4)
是和否。
我的新功能是pthread_kill()函数,它允许您在同一进程下向线程发送信号。
http://linux.die.net/man/3/pthread_kill
注意阅读页面底部的注释......
信号处理是整个流程的:如果安装了信号处理程序,将在线程线程中调用处理程序,但如果信号的处置是“停止”,“继续”或“终止”,则此操作会影响整个过程。
我如何解释这个过程的处理程序将被调用,然后你可以采取适当的行动,只要你满足这些条件就知道只为该线程调用了处理程序。
答案 1 :(得分:3)
您可以使用pthread_kill()
向特定线程发送信号,或者如果您不介意特定于GNU,请使用pthread_sigqueue()
(可以指定一个int
或{{ 1}}处理程序可以通过void *
)进行访问。
每个信号只有一个信号处理程序。这意味着特定信号将始终调用相同的处理函数,无论它恰好是哪个线程。如果一个线程设置了一个新的信号处理程序,那么信号处理程序将针对所有线程进行更改。
但是,解决方法很简单:使用每线程函数指针来定义信号处理程序应该调用哪个函数。只需记住信号处理程序的限制 - 您只能在信号处理程序中使用async-signal safe functions。
info->si_value
原子加载(/* 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));
和函数开关都可以被一个C ++ 11风格的__sync_fetch_and_or()
调用替换,但我还没有足够的GCC,所以我还在使用旧式的__atomic_
电话。
POSIX还支持实时信号,__sync_
,SIGRTMIN+0
,..,SIGRTMIN+1
。它们具有额外的好处,即它们中的一个以上可以同时处于待处理状态。它们比传统信号更适合这种事情。