我正在使用一个应用程序,其中较低级别的应用程序在接收数据时始终调用回调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就会检索它。
答案 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系统上广泛使用的标准。