2

我有一个具有 1+N 个线程和 N 个 FIFO 队列的程序,例如:FIFO_queue_t* fifo_queque[N]。一个线程负责填充这 N 个 FIFO 队列。并且每个其他线程都与 1 个 FIFO 队列相关。

对于每个其他线程 i ,它会继续检查其 FIFO 队列 fifo_queue[i] 是否为空,如果不为空,则从 fifo_queue 中获取所有元素并再次使 fifo_queue 为空。

现在的问题是如何进行检查(如果您愿意,也可以进行轮询)。一种方法是

  for(;;)
  {
     if(fifo_queue[i] != NULL)
     {
          fetch_all_element();
      }
   }

这样一来,可能是很耗CPU的吧?所以另一种方法是使用 pthread_cond_t 变量,

     for(;;){
          pthread_mutex_lock(&mut);
          if(fifo_queue[i] == NULL)  {
                  pthread_cond_wait(&cond, &mut);
                  fetch_all_element();
          }
          pthread_mutex_unlock(&mut);
      }

但是这样,我需要为 N 个线程创建 N 个条件变量和互斥锁。是不是很耗资源?有没有好的方法可以在这种情况下阻塞线程直到它被满足?谢谢!

4

2 回答 2

1

似乎填充队列的线程应该在填充整个队列时向其他线程发出信号。虽然所有条件变量的设置都非常耗时,但当程序超出此初始化周期时,它应该运行得更快,因为您不会浪费 CPU 时间与 N 个线程循环。相反,将运行 1 个线程(填满队列的主线程),然后当它必须运行时,它会向一个线程发出信号,并且该线程将开始执行。主线程是否继续执行取决于您,因为您可能需要添加更多互斥锁以确保主线程不会践踏任何其他线程。

于 2013-05-13T17:26:53.903 回答
0

我正在从事一个听起来与您正在做的事情非常相似的项目。关联

我所做的是创建一个线程安全队列,如果队列为空,它将阻止任何试图从队列中出列的进程,或者如果队列已满,则会阻止试图入队的进程。因此,一旦将条目添加到队列中,就会向消费进程发出信号。这样,您就不会通过轮询每个线程来浪费 CPU 周期。

不确定这是否一定适用于您的场景,但它可能会让您了解如何解决问题。

编辑:这是一个可能有用的附加功能。如果队列为空,则返回“1”。isFull() 的类似函数可以由此创建。

int isEmpty(Queue *q)
{
    int ret;
    sem_wait(q->excl);
    if (q->count <= 0) 
        ret = 1;
    else 
        ret = 0;
    sem_post(q->excl);
    return ret;
}
于 2013-05-13T17:47:09.897 回答