取消或杀死pthread

gcc (GCC) 4.6.3 valgrind-3.6.1 

我创建了一个应用程序,在2个不同的线程中发送和接收一些消息,用于发送和接收。 使用pthreads,条件可变和锁定互斥锁。

但是,发送方将发送消息,然后通知接收方接收消息并进行处理。 它在while循环中执行此操作。

但是,如果我想通过使用ctrl-c并处理中断来退出应用程序,则会出现问题。 如果没有发送消息,则接收器卡在等待接收的while循环中。

主线程将调用join和block等待接收器完成。 但它没有等待pthread_cond_wait

我在考虑使用pthread_cancelpthread_kill 。 但我不喜欢这样做,因为它不允许线程正常退出。

非常感谢任何建议。

主function

  void main(void) { /* Do some stuff here */ /* Start thread that will send a message */ if(pthread_create(&thread_recv_id, &thread_attr, thread_recv_fd, NULL) == -1) { fprintf(stderr, "Failed to create thread, reason [ %s ]", strerror(errno)); break; } printf("Start listening for receiving data'\n"); /* Start thread to receive messages */ if(pthread_create(&thread_send_id, &thread_attr, thread_send_fd, NULL) == -1) { fprintf(stderr, "Failed to create thread for receiving, reason [ %s ]", strerror(errno)); break; } /* Clean up threading properties */ pthread_join(thread_send_id, NULL); pthread_join(thread_recv_id, NULL); <---- blocking here waiting for the recv thread to finish pthread_mutex_destroy(&mutex_queue); pthread_cond_destroy(&cond_queue); return 0; } 

发送者线程

 void *thread_send_fd() { pthread_mutex_lock(&mutex_queue); if(send_fd((int)fd) == FALSE) { /* Just continue to send another item */ continue; } /* Signal the waiting thread to remove the item that has been sent */ pthread_cond_signal(&cond_queue); pthread_mutex_unlock(&mutex_queue); } 

接收线程

 void *thread_recv_fd() { while(is_receiving()) { pthread_mutex_lock(&mutex_queue); /* Wait for an item to be sent on the queue */ pthread_cond_wait(&cond_queue, &mutex_queue); <---- waiting here queue_remove(); pthread_mutex_unlock(&mutex_queue); } pthread_exit(NULL); } 

你基本上有3个选择:

  1. 使用pthread_cancel 。 这将中断pthread_cond_wait调用,然后退出线程,调用在pthread_cleanup_push注册的取消处理程序。

  2. 使用pthread_kill线程发送信号 。 这不会“杀死”线程,它只是发送一个信号。 在这种情况下,您必须在该线程中为您使用的信号注册信号处理程序,并且该信号处理程序必须执行某些操作以告知线程退出。 这并不比第三个选项好,因为信号处理程序仍然需要做一些事情来使pthread_cond_wait循环退出。

  3. 为您的线程添加手动中断function,该function知道设置标志并发出条件变量信号。 然后,如果设置了标志,那么pthread_cond_wait周围的循环应检查该标志并退出该线程。

我建议(1)或(3)。 使用pthread_cancel是最通用的,但需要在线程中仔细处理,以确保有合适的pthread_cleanup_push调用来清理线程分配的所有资源,解锁所有互斥锁等等。 编写手动中断function可能会带来更多工作,但最容易为您的应用程序量身定制。