【问题标题】:pthread_kill() not sending signal to main thread (main program)pthread_kill() 不向主线程(主程序)发送信号
【发布时间】:2018-01-06 20:59:15
【问题描述】:

信号可以在任何线程或主程序本身中接收。 我从主程序创建了一个辅助线程。所以我的程序中有两个线程 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】:

来自 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 之前这样做,你需要在你的辅助线程中解除阻塞。

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

【讨论】:

  • 感谢您对信号处置和信号掩码的澄清,主要是“sigaction调用正在为整个过程设置信号处置”。我只是不想在辅助线程中接收信号,只想在主线程中接收所有信号,所以我只是在子线程中使用 pthread_sigmask 阻止所有信号。现在我可以看到(使用信号处理程序)所有信号仅接收到主线程(太好了!!)。但是我使用while循环从终端发送相同的信号一样快,所有信号都在主线程中接收(没关系)但我没有收到来自终端的所有发送信号
  • 嗨史蒂文,你是正确的“主线程可能正在获取信号,运行信号处理程序,然后立即再次将信号发送给自己。”在我的系统中,对于信号的 100 次试验,有 25 个信号(此计数因 100 次试验的不同集合而异)进入子线程,其余信号进入主线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 2018-04-29
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多