0

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

在回调中,我创建了两个线程并将消费者和生产者函数分别传递给这些创建的线程。

我的代码:

无效的 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 就会检索它。

4

2 回答 2

1

我相信你想要做的是控制对队列的访问。你会想看看使用互斥锁来控制从队列中读取。

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

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

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

我希望这是有道理的。

于 2009-03-13T05:34:22.297 回答
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 系统上广泛使用的标准。

于 2009-03-13T07:07:13.133 回答