How to send a cancel request from main () to a thread?

I need to block the Ctrl+C signal ( SIGINT ) in thread_B, and main () should handle the SIGINT signal, so whenever a user presses Ctrl+C main (), should try to cancel thread_B, but thread_B should ignore any cancellation of the request for the first 100 seconds, and any cancellation request should be executed after 100 seconds, and after completion of the interruption thread_B main () should be completed, so far Im able to block the signal in thread_B, but could not send the cancellation request to thread_B from main (), as I solve it?

Edit: when a thread is started while the SIGINT loop is disabled, it will not satisfy any request of Ctrl+C , so it will be in the loop forever, how does main() break the while loop so that it can send a cancel request to the thread? any views on this?

code:

 #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); } 
+5
source share
1 answer

You are not sending a cancellation from main () to pthread. The signal handler will do this. main () will continue until it receives the same notification from the signal handler.

See below...

 #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <pthread.h> #include <stdbool.h> static bool shutdown; static bool thread_finished; pthread_t thread; void *thread_func(void *ptr) { while (!shutdown) { int countdown = 5; while (!shutdown && countdown--) { usleep(250 * 1000); } printf("Still waiting...\n"); } printf("Shutdown signal flag set. Closing."); thread_finished = true; return 0; } void sigint_handler(int sig) { if (sig == SIGINT) { // handle shutdown // If you need to bypass then do it here printf("Sending shutdown signal to thread\n"); shutdown = true; pthread_join(thread, NULL); } } int main() { signal(SIGINT, sigint_handler); printf("Starting background thread!\n"); shutdown = false; thread_finished = false; pthread_create(&thread, NULL, &thread_func, (void*)0); while (!shutdown && !thread_finished) { usleep(1500 * 1000); printf("Still running from main\n"); } return 0; } 

You can use the same mechanism to turn off multiple threads before your application finally leaves itself.

+1
source

Source: https://habr.com/ru/post/1273008/


All Articles