提高SIGINT,但在c中陷入线程

时间:2017-12-10 04:06:38

标签: c linux multithreading signals

我正在做一个利用线程的程序。我还有一个SIGINT处理程序,可以正常关闭所有内容,以便有序关闭。但是,由于我的线程处于while(1)循环中,我的处理程序中的pthread_join函数被卡住了,我必须多次按ctrl+c,以便单独关闭每个线程。如何只需点击一下即可完成此操作? 这是我的线程工作者函数:

void *worker(){
    struct message msg;
    while(1){
      if(wr.fnode != NULL){
        sem_wait(&tsem);
        stats->nptri++;
        msg.patient = *(wr.fnode);
        wr_deletefnode();
        sem_post(&tsem);
        sleep((float)(msg.patient.ttime/1000));
        msgsnd(mqid,&msg,sizeof(msg)-sizeof(long),0);
      }
    }
}

2 个答案:

答案 0 :(得分:1)

这取决于您如何向signal发送thread(SIGINT或任何)。为了向线程发送信号,您应该使用pthread_kill()而不是kill()raise(),因为信号处理程序(signal or sigaction)仅处理processes,而不是threads }。

 int pthread_kill(pthread_t thread, int sig);

如果您尝试使用kill命令/函数杀死正在运行的线程,操作系统将抛出警告Warning: Program '/bin/bash' crashed.

在发送信号之前和之后使用ps -eL | grep pts/0观察正在运行的线程。

我希望你有所收获。

答案 1 :(得分:0)

您需要解决两件事:

  1. 如何打破无尽的循环
  2. 如何从阻止系统调用返回(例如sem_wait()
  3. 参考1:

    更改

    while (1)
    

    while (!exit_flag)
    

    全球定义exit_flag

    volatile sig_atomic_t exit_flag = 0;
    

    并在收到1信号时将其设置为SIGINT

    要捕获信号,请不要设置信号处理程序,而是使用sigwait()创建一个单独的线程来等待并接收SIGINT

    确保创建阻止SIGINT

    的所有其他线程

    参考2:

    通过记忆他们的线程ID来跟踪所有正在运行的线程。

    在1.下面提到的信号监听器线程之后设置exit_flag,然后循环遍历正在运行的线程列表并逐个

    • 让他们接收SIGINT
    • 使用pthread_kill()发出信号,如果它们被卡在系统调用中,则调用会将errno设置为EINTR
    • 加入调用pthread_join()
    • 的主题