取消信号处理程序内的线程

时间:2012-07-20 07:02:08

标签: c++ c linux multithreading signals

我已启动计时器并将间隔设置为5秒并为其注册了信号处理程序。 当遇到SIGALRM我试图终止信号处理程序内的线程时,bt无法做到这一点。线程没有被终止,而是整个进程被杀死 以下是代码:

 void signalHandler()
{
        printf("Caught signal ...\n");
        printf("Now going to terminate thread..\n");
        pthread_kill(tid, SIGKILL);
}

void * thread_function()
{
        int oldstate;
        char result[256] = {0};
        time_t startTime = time(NULL);
        time_t timerDuration = 5;
        time_t endTime = startTime + timerDuration;

        while(1) {
                printf("Timer is runnuing as dameon..\n");
                if(!strcmp(result, "CONNECTED")) {
                        resp = 1;
                        pthread_exit(&resp);
                }
        }
}

int main()
{
        int *ptr[2];

        signal(SIGALRM, signalHandler);

        timer.it_interval.tv_usec = 0;
        timer.it_interval. tv_usec = 0;

        timer.it_value.tv_sec = INTERVAL;
        timer.it_value.tv_usec = 0;

        setitimer(ITIMER_REAL, &timer, 0);
            pthread_create(&tid, NULL, thread_function, NULL);
        pthread_join(tid, (void**)&(ptr[0]));
        printf("test %d\n\n",*ptr[0]);

        while(1)
                printf("1");
}

平台:Linux,gcc编译器

3 个答案:

答案 0 :(得分:2)

据我所知,你几乎不能在信号处理程序中调用任何东西,因为你不知道你的代码处于什么状态。

您最好的选择是设置一个线程来处理您的信号。所有其他线程都应该调用pthread_setsigmask并阻止所有信号,然后创建另一个线程,调用调用pthread_setsigmask来捕获SIGALARM,然后调用sigwait,它可以取消另一个线程。

答案 1 :(得分:1)

与单线程环境相比,多线程环境中处理信号的方式大不相同。在多线程代码中,您应该阻止所有具有业务逻辑的线程的所有信号,然后创建一个单独的线程来处理信号。这是因为,在多线程环境中,您无法确定信号将传递到哪个线程。

有关详细信息,请参阅此链接:
http://devcry.heiho.net/2009/05/pthreads-and-unix-signals.html

除此之外,要杀死一个使用pthread_cancel的线程,它应该可以正常工作。

答案 2 :(得分:0)

您可以尝试使用旗帜:

int go_on[number_of_threads] = { 1 };

void signalHandler()
{
        printf("Caught signal ...\n");
        printf("Now going to terminate thread..\n");
        go_on[tid] = 0;
}

void * thread_function()
{  /* */
   while(go_on[this_thread_id]) {
                printf("Timer is runnuing as dameon..\n");
                if(!strcmp(result, "CONNECTED")) {
                        resp = 1;
                        pthread_exit(&resp);
                }
   }
}