我有一个相当简单的情况:我在一个线程中有一个高速数据生产者,它生成一个包含[可变长度]元素的缓冲区。一旦这个缓冲区被填满,我就有一个消费者将它写入磁盘。
现在,如果缓冲区尚未被消费者线程写入,则需要尽快恢复生产的生产者线程会旋转到位:
int volatile datatogo=0; // global with starting condition
while(datatogo != 0) // spin, buffer not yet written out
{
if (recflag == 0) return; // recording is terminated
}
// clipped code fills buffer, then:
datatogo = lengthoffill;
...在另一个线程中,缓冲区写入器执行以下操作:
while(recflag)
{
if (datatogo)
{
if (m_File.write(sbuffer,datatogo) == -1)
{
recflag=0; // bail NOW
}
datatogo = 0; // buffer transferred
}
usleep(100); // 100 uS
}
这样做的最终结果是,写入磁盘的消费者在完成写入后放弃了 CPU,因为它知道生产者将需要一些时间来实际填充缓冲区。当消费者在没有数据时处于休眠状态,CPU 可供生产者使用。消费者睡眠 100 uS,检查数据,如果没有数据则返回睡眠,因此它在该状态下除了睡眠之外并没有做太多事情。
然而,由于睡眠时间是任意的,这不太可能是最佳的。即使我仔细调整它以在我的机器上工作(8 核,3 GHz),它在另一台机器上的作用也会不同。有时数据已经准备好写入,而消费者刚刚入睡,可以这么说,将整个 100 uS 扔出窗外。我也对如此小的时间窗口的分辨率和可靠性感到不安——而更大的窗口将无法工作。
所以。Qt中有多种机制可以控制对事物的访问,这本质上是我想要做的。但我不明白哪一个(如果有的话)会做我想做的事,那就是:
1)让消费者睡眠直到缓冲区已满,然后写入并重新进入睡眠状态,或者直到作业停止以便它可以关闭文件(它可以在唤醒时检查哪个)
2) 当生产者睡眠时,仅当缓冲区被写出时,否则填充缓冲区并返回生产其内容。
我需要尽可能多的可用 CPU ——这是一个软件定义的无线电应用程序,到处都有数据飞来飞去,多个 FFT 正在运行,各种图形 hoo-ha 发生等等。旋转时间很糟糕,很糟糕。
有什么好心人能指点我使用的理想 Qt 机制吗?我发现 QMutex、QWaitCondition、QSemaphore 上的 Qt 文档...有点不透明。