提高SIGINT,但卡在c中的线程中

提高SIGINT,但卡在c中的线程中,c,linux,multithreading,signals,C,Linux,Multithreading,Signals,我正在做一个利用线程的程序。我还有一个SIGINT处理程序,可以正确地关闭所有内容,以便有序地关闭。但是,由于我的线程处于循环中,而(1)循环中,我的处理程序中的pthread\u join函数被卡住,我必须按ctrl+c多次才能单独关闭每个线程。我如何只需单击一次就可以做到这一点? 下面是我的线程辅助函数: void *worker(){ struct message msg; while(1){ if(wr.fnode != NULL){ sem_

我正在做一个利用线程的程序。我还有一个
SIGINT
处理程序,可以正确地关闭所有内容,以便有序地关闭。但是,由于我的线程处于
循环中,而(1)
循环中,我的处理程序中的
pthread\u 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);
      }
    }
}

这取决于您如何将
信号
(SIGINT或any)发送到
线程
。要向线程发送信号,您应该使用
pthread\u kill()
而不是
kill()
raise()
,因为信号处理程序(
signal或sigaction
)只处理
进程,而不是
线程

 int pthread_kill(pthread_t thread, int sig);
如果您试图使用kill命令/函数终止正在运行的线程,操作系统将抛出类似于
警告:程序'/bin/bash'崩溃的警告。

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


我希望你能有所收获。

你需要解决两件事:

  • 如何打破无休止的while循环
  • 如何从阻止系统调用返回(例如
    sem\u wait()

  • 参考1.:

    改变

    while (1)
    
    将来

    while (!exit_flag)
    
    全局定义退出标志

    volatile sig_atomic_t exit_flag = 0;
    
    并在接收到
    SIGINT
    信号时将其设置为
    1

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

    确保所有其他线程都是通过阻塞
    SIGINT
    创建的


    参考2.:

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

    在1中提到的信号侦听器线程之后。设置退出标志,然后逐个循环运行线程列表

    • 使他们能够接收
      SIGINT
    • 使用
      pthread\u kill()
      向它们发送信号,如果它们被卡在系统调用中,调用会将设置
      errno
      返回到
      EINTR
    • 加入调用
      pthread\u join()
      的线程

    如果线程位于它的工作中间,并且我希望/它需要在<代码>之前完成。有没有一种方法可以阻止或取消阻止线程接收特定信号?感谢您的回复。我以前没有尝试过,但您可以使用
    pthread\u cond\u signal()
    它将解除对条件变量阻塞的线程的阻塞。检查手册页有这么多,你会得到。不要调用pthread_join?发布你的信号处理程序。“我还有一个SIGINT处理程序,它可以正确地关闭所有内容,以便有序地关闭。”听起来您可能是在信号处理程序中调用非异步信号安全函数,这是一种很好的进程死锁方法。谢谢您的回答。不幸的是,我需要使用一个处理器来捕捉我的信号,否则你的解决方案会更优雅。关于,
    exit_标志
    部分。这不是在积极等待吗?我不知道这个词是否正确(我是从我自己的语言翻译过来的)。@jonelearn:“这不是在进行主动等待吗?”我不明白这个问题?如果需要使用信号处理程序,请在其内部设置
    exit_标志
    ,并在专用终止线程内部设置,如1所述。将对
    sigwait()
    的调用替换为
    while(!exit_flag){sleep(1);}
    。您输入了一个错误。应该是“确保创建了所有其他线程,阻止
    SIGINT
    ”@NominalAnimal:Hu!谢谢固定的。