如何从main()发送取消请求到线程?

时间:2017-10-30 16:48:43

标签: c multithreading signals posix

我需要在thread_B中阻止Ctrl+C信号(SIGINT)并且main()应该处理SIGINT信号,所以每当用户按下Ctrl+C时main()应该尝试取消thread_B但是thread_B需要忽略前100秒的任何取消请求,并且任何取消请求应该在100秒后得到兑现,并且在thread_B终止后main()应该终止,到目前为止我能够阻止thread_B中的信号但是不能发送取消请求从main()到thread_B,我该如何解决?

编辑: 当线程在while循环SIGINT被禁用时运行时,它将不会接受任何Ctrl+C请求,因此它将永远循环,main()将如何中断while循环以便它可以向线程发送取消请求?对此有何看法?

代码:

#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <math.h>

#define handle_error_en(en, msg) \
       do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static volatile sig_atomic_t doneflag = 0;

/* ARGSUSED */
static void setdoneflag(int signo) {
    doneflag = 1;
}

static void *
thread_func(void *ignored_argument)
{
   int s;

    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGINT);
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    while (!doneflag)
    {

        sleep(1);
        printf("Hello\n");

       s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
       if (s != 0)
           handle_error_en(s, "pthread_setcancelstate");

       printf("thread_func(): started; cancellation disabled\n");
       sleep(5);
       printf("thread_func(): about to enable cancellation\n");

       s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
       if (s != 0)
           handle_error_en(s, "pthread_setcancelstate");

       /* sleep() is a cancellation point */

       sleep(10);        /* Should get canceled while we sleep */

       // /* Should never get here */

       // printf("thread_func(): not canceled!\n");
    }

        return NULL;

}

int
main(void)
{
   pthread_t thr;
   void *res;
   int s;

   sigset_t sigset;

   int recvdSig;
   sigwait(&sigset,&recvdSig);

   s = pthread_create(&thr, NULL, &thread_func, NULL);
   if (s != 0)
       handle_error_en(s, "pthread_create");

   //sleep(2);           /* Give thread a chance to get started */

    if( recvdSig == SIGINT )
        {
            printf("main(): sending cancellation request\n");
            s = pthread_cancel(thr);
            if (s != 0)
               handle_error_en(s, "pthread_cancel");
        }

    struct sigaction act;
    act.sa_handler = setdoneflag;            /* set up signal handler */
    act.sa_flags = 0;
    if ((sigemptyset(&act.sa_mask) == -1) || (sigaction(SIGINT, &act, NULL) == -1)) 
    {
        perror("Failed to set SIGINT handler");
        return 1;
    }

   /* Join with thread to see what its exit status was */

   s = pthread_join(thr, &res);
   if (s != 0)
       handle_error_en(s, "pthread_join");

   if (res == PTHREAD_CANCELED)
       printf("main(): Terminated\n");
   else
       printf("main(): thread wasn't canceled (shouldn't happen!)\n");
   exit(EXIT_SUCCESS);
}

1 个答案:

答案 0 :(得分:1)

您不能将取消从main()发送到pthread。信号处理程序将这样做。 main()将继续,直到它收到来自信号处理程序的相同通知。

见下文......

{{1}}

在应用程序最终退出之前,您可以使用相同的机制关闭多个线程。