c - pthread condition not being satisfied -
i creating multi threaded application runs forever until user sends interrupt (i.e. ctrl+c), output_report() method run. here sample of code:
void output_report(int signo) { printf("exiting!\n"); pthread_mutex_lock(&mutex_num_of_threads); programclosing = true; while (numofthreads != 0){ pthread_cond_wait(&allthreadscompletecond, &mutex_num_of_threads); } pthread_mutex_unlock(&mutex_num_of_threads); printf("closing now!\n"); //this part not reached pthread_exit(null); // needed? exit(0); } void dispatch(struct pcap_pkthdr *header, const unsigned char *packet, int verbose) { static bool thread_settings_initialised = false; //only run first time dispatch method runs if (thread_settings_initialised == false){ thread_settings_initialised = true; if (signal(sigint, output_report) == sig_err) fprintf(stderr, "\ncan't catch sigint\n"); //... //set mutex appropriate variables remain thread safe pthread_mutex_init( &mutex_num_of_threads, null); //... //set attr threads "detached" pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, pthread_create_detached); //set pthread_cond_init pthread_cond_init(&allthreadscompletecond, null); } //... pthread_mutex_lock(&mutex_num_of_threads); numofthreads++; pthread_mutex_unlock(&mutex_num_of_threads); //... int rc = pthread_create( &tid, &attr, analyse, (void *) &data); //... } void analyse(void *thread_data) { //... pthread_mutex_lock(&mutex_num_of_threads); numofthreads--; if (programclosing == true && numofthreads == 0) { pthread_cond_signal(&allthreadscompletecond); } pthread_mutex_unlock(&mutex_num_of_threads); pthread_exit(null); }
my problem when ever use ctrl+c, program sort of halts (not exit,as program still running. have use ctrl+z out of it). program outputs "exiting" not "closing now" meaning "allthreadscompletecond" not being met, i'm not sure why.
update
thanks paul griffiths answer updated code so:
void exithandler(int signum){ programclosing = 1; } void output_report(int signo) { while (programclosing == 1){ printf("exiting!\n"); //rest same before exit(0) } } void dispatch(struct pcap_pkthdr *header, const unsigned char *packet, int verbose) { static bool thread_settings_initialised = false; int rc; printf("dispatch!\n"); //only run first time dispatch method runs if (thread_settings_initialised == false){ thread_settings_initialised = true; //set mutex appropriate variables remain thread safe //.. //set attr threads "detached" //.. //... if (signal(sigint, exithandler) == sig_err) fprintf(stderr, "\ncan't catch sigint\n"); pthread_t exit_tid; rc = pthread_create( &exit_tid, &attr, output_report, (void *) null); if (rc) { printf("error; return code pthread_create() %d\n", rc); exit(-1); } } //... ///same before }
now updated code still not output text "exiting"!
printf()
, , particularly, here, pthread_mutex_lock()
, pthread_cond_wait()
, pthread_mutex_unlock()
not safe call signal handlers. behavior you're seeing evidence of that. can ok so, getting there involves making sure rest of program can't possibly adversely affected doing so, non-trivial programs not feasible.
signal handling can tricky enough start with, , in general, mixing threads , signals makes things more tricky. general approach (1) call functions async-signal-safe signal handler (you can find list of them here); , (2) little work in signal handler possible. you'll need think (3) blocking delivery of signal or signals critical sections don't want set of operations interrupted signal handler might adversely interfere operations.
variables of type volatile sig_atomic_t
can safely written signal handler, common strategy have signal handler nothing set such variable, main program periodically checks. instance:
volatile sig_atomic_t im_done = 0; void handler(int signum) { im_done = 1; } int main(void) { /* init stuff , register signal handler */ while ( !im_done ) { /* main work here */ } /* clean , ready exit here */ return 0; }
Comments
Post a Comment