pthread_cond_broadcast()会导致其他函数调用失败吗?

时间:2012-10-29 13:36:57

标签: c++ c pthreads system-calls

这个问题是this question的后续问题。总结是 - 我有一个服务器调用close()来完成连接,但似乎关闭序列从未发生过。客户继续等待更多数据。 close()在服务器中返回0。即使条件队列正确实现,将我的线程安全队列从条件等待切换到信号量也解决了问题。我正在发布我的代码,看看是否有人对我这些事情有任何启发。

基于条件的队列:

  TASK *head;
  pthread_mutex_t mutex;
  pthread_cond_t cond;

  void init( ) {
    head = NULL;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
  }

  TASK *get( ) {
    pthread_mutex_lock( &mutex );
    while(!head)
      pthread_cond_wait(&cond, &mutex);
    TASK *res = head;
    head = head->next;
    pthread_mutex_unlock( &mutex );
    return res;
  }

  void add( TASK *t ) {
    pthread_mutex_lock( &mutex );
    t->next = head;
    head = t;
    pthread_cond_broadcast( &cond );
    pthread_mutex_unlock( &mutex );
  }

我确实知道这是一个LIFO队列,下一个是FIFO,但我只包含了有趣的位,所以它很容易阅读。

基于信号量的队列:

  TASK *buf;
  TASK *next_reader;
  TASK *next_writer;
  TASK *endp;
  pthread_mutex_t writer_mutex;
  pthread_mutex_t reader_mutex;
  sem_t writer_sem;
  sem_t reader_sem;

  void init( int num_tasks ) {
    buf = calloc(sizeof(TASK), num_tasks);
    next_reader = buf;
    next_writer = buf;
    endp = buf + num_tasks;
    sem_init(&writer_sem, 0, num_tasks);
    sem_init(&reader_sem, 0, 0);
    pthread_mutex_init(&writer_mutex, NULL);
    pthread_mutex_init(&reader_mutex, NULL);
  }

  TASK *get( ) {
    TASK *res = NULL;
    sem_wait(&reader_sem);
    pthread_mutex_lock(&reader_mutex);
    res = next_reader;
    next_reader++;
    if(next_reader == endp)
      next_reader = buf;
    pthread_mutex_unlock(&reader_mutex);
    sem_post(&writer_sem);
    return res;
  }

  void add( TASK *t ) {
    sem_wait(&writer_sem);
    pthread_mutex_lock(&writer_mutex);
    *next_writer = *item;
    next_writer++;
    if(next_writer == endp)
      next_writer = buf;
    pthread_mutex_unlock(&writer_mutex);
    sem_post(&reader_sem);
  }

我不能为我的生活看到从条件队列到信号量队列的更改如何解决我发布的上一个问题,除非在线程关闭套接字并且在调用pthread_cond_broadcast期间发生了一些时髦的事情关闭。我假设一个os bug,因为我找不到任何文件谴责我正在做的事情。没有从信号处理程序调用队列操作。这是我的发行版:

Linux版本:2.6.21.7-2.fc8xen

Centos版本:5.4(最终版)

由于

编辑----我刚刚在我正在做的初始化中添加了。在实际代码中,这些是在模板化的类中实现的。我刚刚收录了相关部分。

0 个答案:

没有答案