如何使用两个线程的队列 - 一个用于消费者,一个用于生产者

时间:2009-03-13 05:27:51

标签: multithreading queue

我正在使用一个应用程序,其中较低级别的应用程序在接收数据时始终调用回调RecData(char * buf)。

在回调中,我创建了两个线程,并将consumer和producer函数分别传递给这些创建的线程。

我的代码:

void RecData(char * buf) {

CreateThread(NULL,0,producer_queue,(void *)buf,0,NULL);
CreateThread(NULL,0,consumer_queue,NULL,0,NULL);

}

当我一次收到一个数据时,上述工作正常。如果我几乎同时收到5个数据,那么producer_queue应该首先将所有数据放入队列,然后consumer_queue应该开始检索数据,但是只要producer_queue将第一个数据放入队列,consumer_queue就会检索它。

2 个答案:

答案 0 :(得分:1)

我认为,您想要做的是控制对队列的访问。您将需要查看使用互斥锁来控制队列中的读取。

收到数据后,您将锁定互斥锁,然后将数据排入队列。完成数据排队后,请释放锁定。

从队列中读取时,您将看到互斥锁是否已锁定。如果要将数据写入队列,则在生成器线程完成写入所有数据并释放锁定之前,您将无法开始读取。如果您实际上锁定了互斥锁,那么在读取数据时会阻止写入程序线程写入。

这种方法可能会引入潜在的死锁。如果你的编写器线程在释放锁之前死掉,那么你的读者线程将无法继续(那么你的线程死亡可能只会触发错误状态)。

我希望这是有道理的。

答案 1 :(得分:0)

使用条件变量的概念。您遇到的问题是多线程编程领域中最常见的问题。只使用互斥锁对情况没有帮助。永远记住,互斥锁用于锁定和放置。条件变量用于等待。当线程应该从共享队列开始消费时,后者总是更安全且几乎可以确定。

查看以下链接,了解如何在Windows上自行创建条件变量:      http://www.cs.wustl.edu/~schmidt/win32-cv-1.html

如果您使用的是Windows Vista,则以下msdn示例可能会对您有所帮助:     http://msdn.microsoft.com/en-us/library/ms686903(VS.85).aspx

在所有情况下都使用Schmidt网站上显示的逻辑,因为它看起来更便携(哦,至少可以在不同版本的Windows上移植)。 Schmidt的实现为您提供标准的POSIX api感觉,这是大多数现代UNIX / LINUX系统上广泛使用的标准。