2012-04-12 80 views
1
gcc (GCC) 4.6.3 
valgrind-3.6.1 

我创建了一个应用程序,发送和接收一些消息在2个不同的线程发送和接收。使用pthreads,为锁定调整可变参数和互斥量。取消或杀死一个pthread

但是,发送者将发送消息,然后发信号通知接收者接收并处理它。它在一个while循环中完成。

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

主线程将调用加入并阻止接收方完成。但它不像它在等待pthread_cond_wait

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

非常感谢您的任何建议。

主要功能

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); 
} 
+1

如果您不加入到recv线程,它不会阻止您的主线程退出,并且操作系统将停止这两个线程。如果recv线程不包含进程间资源等,则让操作系统停止它。 – 2012-04-12 08:27:22

回答

9

你B asically有3个选择:

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

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

  3. 向您的线程添加一个手动中断功能,该功能知道要设置一个标志并指示条件变量。如果标志被设置,则围绕pthread_cond_wait的循环应检查标志并退出线程。

我会推荐(1)或(3)。使用pthread_cancel是最通用的,但需要在线程中谨慎处理,以确保有合适的pthread_cleanup_push调用清理线程分配的所有资源,解除所有互斥锁等。编写手动中断功能可能会有更多的工作,但可以根据您的应用程序轻松定制。

+4

4.在没有必要时停止使用连接。 – 2012-04-12 08:28:41