无法在多线程程序中捕获SIGINT信号

时间:2015-02-08 04:43:02

标签: c

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

sigset_t set;
int sigint_signal = 0;
pthread_t monitor_thread, demo_thread;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

void *monitor()
{

    while(1)
    {
        sigwait(&set, NULL);
        pthread_mutex_lock(&m);
        printf("__SIGINT received__\n");
        sigint_signal = 1;
        pthread_cancel(demo_thread);
        pthread_mutex_unlock(&m);
    }

}

void *demo_function(){
    while(1){
        pthread_mutex_lock(&m);
        fprintf(stdout, "__Value of SIGNAL FLAG %d:__\n",sigint_signal);
        pthread_mutex_unlock(&m);
    }
    return NULL;
}

int main(){

    sigemptyset(&set);
    sigaddset(&set,SIGINT);
    pthread_sigmask(SIG_BLOCK,&set,0);

    pthread_create(&monitor_thread, 0, monitor, NULL);
    pthread_create(&demo_thread, 0, demo_function, NULL);

    pthread_join(demo_thread, NULL);
    return 0;
}

monitor_thread是持续运行以捕获SIGINT信号的线程。收到信号后,它必须取消另一个线程并结束。 收到SIGINT后,可以使用变量sigint_signal的值来验证,一旦收到信号,变量1变为pthread_cancel。但是sigint_signal没有被执行,因为一旦1的值{1}}更改为demo_thread,{{1}}继续运行。请帮助。

1 个答案:

答案 0 :(得分:1)

阅读文档:http://man7.org/linux/man-pages/man3/pthread_cancel.3.html

在那里你会看到pthread_cancel不能保证立即杀死线程,而是取决于该线程的状态。默认情况下,取消只能在取消点进行,其中包括write(),可能间接包含printf()

无论如何,真正的解决方案是根本不使用pthread_cancel,而是使用sigint_signal作为while中的demo_function循环条件。

至于为什么pthread_cancel是一个坏主意,这是因为一般来说,函数通常不是以他们准备死的方式编写的。在异步终止执行的上下文中很难推断资源管理。