我正在做一个利用线程的程序。我还有一个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);
}
}
}
答案 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)
您需要解决两件事:
sem_wait()
)参考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()
。