c++ - 我可以向不同的线程发送信号吗

标签 c++ c linux gcc x86

假设我有一个线程 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() (可以指定一个 intvoid * 处理程序可以通过 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/

相关文章:

c++ - For循环除数

c++ - vector 元素似乎没有连续存储

c - 从C中的txt文件打印矩阵

c - 下面代码中的 char 元素与十六进制数字相比如何?

linux - 在某些文件夹名称中搜索特定文本字符串 - Linux 2.6

c++ - 进程C的动态池

c++ - "LNK1561 entry point must be defined"用于简单程序

使用 gcc c99 编译,而不是使用 ideone c99。整数溢出

linux - 构建自定义 Linux Live CD

c++ - Windows 上 C 库的二进制交叉编译器兼容性