pthread_kill() 不向主线程(主程序)发送信号

问题描述 投票:0回答:1

信号可以被任何线程或主程序本身接收。 我从主程序创建了一个辅助线程。所以我的程序中有两个线程

  1. 主线程(进程本身)
  2. 辅助线程。

我希望每当信号到达我的辅助线程时,它就应该向我的主线程(程序)发送信号。我正在使用

pthread_kill(main_threadid, sig)
从辅助线程内的信号处理程序寄存器发送信号。但是,我观察到每次发送到主线程的信号接收到辅助子线程本身,并且信号处理程序陷入接收发送信号的循环中。

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

// global variable
pthread_t main_threadId;
struct sigaction childpsa;

// Signal Handler for Auxiliary Thread  
void signalHandler_Child(int param)
{
    printf("Caught signal: %d in auxiliary Thread", param);
    pthread_kill(main_threadId, param);
}

void *childFun(void *arg)
{
    childpsa.sa_handler = signalHandler_Child;
    sigaction(SIGTERM, &childpsa, NULL);
    sigaction(SIGHUP, &childpsa, NULL);
    sigaction(SIGINT, &childpsa, NULL);
    sigaction(SIGCONT, &childpsa, NULL);
    sigaction(SIGTSTP, &childpsa, NULL);

    while (1) {
        // doSomething in while loop
    }
}

int main(void)
{
    main_threadId = pthread_self();

    fprintf(stderr, "pid to signal %d\n", getpid());

    // create a auxiliary thread here
    pthread_t child_threadId;
    int err = pthread_create(&child_threadId, NULL, &childFun, NULL);

    while (1) {
        // main program do something 
    }

    return 1;
}

假设我正在使用进程 ID 从终端发送 SIGINT 到进程。

linux signals posix multithreading
1个回答
3
投票

摘自Unix环境下的高级编程:

每个线程都有自己的信号掩码,但信号处置由进程中的所有线程共享。这 意味着单个线程可以阻塞信号,但是当线程修改与给定关联的操作时 信号,所有线程共享该操作。因此,如果一个线程选择忽略给定信号,另一个线程可以撤消 通过恢复默认配置或为信号安装信号处理程序来进行选择。

sigaction
调用正在设置整个进程(以及该进程中的所有线程)的信号处置。

当您向进程发送信号时,任何未阻止该信号的线程(但只有 1 个线程)都可以接收该信号(尽管根据我有限的经验,通常首选主线程)。在您的代码中,主线程可能会获取信号,运行信号处理程序,然后立即再次向自身发送信号。

如果您希望单个辅助线程处理进程的所有信号,您可以在主线程中使用 pthread_sigmask 来阻止有问题的信号:

sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGCONT);
sigaddset(&set, SIGTSTP);
pthread_sigmask(SIG_BLOCK, &set, NULL);

这将确保信号不会传递到该线程。如果您在 pthread_create 之前执行此操作,则需要在辅助线程中取消阻止它们。

然后您可以使用非信号线程间通信机制来与主线程通信。

© www.soinside.com 2019 - 2024. All rights reserved.