fyn*_*yrz 1 qt multithreading producer-consumer
我有一个相当简单的情况:我在一个线程中有一个高速数据生成器,它生成一个带有[变长]元素的缓冲区.填充此缓冲区后,我有一个将其写入磁盘的使用者.
现在,生成器线程需要返回生成ASAP,如果缓冲区尚未被消费者线程写入,则会旋转到位:
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;
Run Code Online (Sandbox Code Playgroud)
...在另一个线程中,缓冲区编写器执行此操作:
while(recflag)
{
if (datatogo)
{
if (m_File.write(sbuffer,datatogo) == -1)
{
recflag=0; // bail NOW
}
datatogo = 0; // buffer transferred
}
usleep(100); // 100 uS
}
Run Code Online (Sandbox Code Playgroud)
这样做的最终结果是写入磁盘消费者在完成写入时放弃了CPU,知道生产者必须花一些时间来实际填充缓冲区.当消费者在没有数据时睡着了,CPU可供生产者使用.消费者睡眠时间为100 uS,检查数据,如果没有,则返回睡眠状态,因此除了睡眠状态之外,它在该状态下没有做太多事情.
但是,因为睡眠时间是任意的,所以这不可能是最佳的; 即使我仔细调整它以在我的机器上工作(8核,3 GHz),它在另一台机器上的行为也会不同.有时会有数据准备好被写入,消费者刚刚进入睡眠状态,将整个100美元扔出窗外,可以这么说.我也对这种小型计时窗口的分辨率和可靠性有疑虑 - 而较大的窗口将无法工作.
所以.Qt中有多种机制来控制对事物的访问,这基本上就是我想做的事情.但我不明白哪一个(如果有的话)会做我想做的事,这是:
1)让消费者睡眠直到缓冲区已满,然后写入并返回睡眠状态,或直到作业停止,这样它就可以关闭文件(它可以检查唤醒时哪个)
2)当生成器只在缓冲区被写出时才会休眠,否则填充缓冲区并返回生成其内容.
我需要尽可能多的CPU可用 - 这是一个软件定义的无线电应用程序,有数据飞来飞去,运行多个FFT,各种图形发生,等等.旋转时间很糟糕,很糟糕.
某种灵魂可以指向我理想的Qt机制吗?我发现QMutex,QWaitCondition,QSemaphore上的Qt文档有点不透明.
标记整数变量volatile不足以满足多线程程序的要求:
为什么volatile在多线程C或C++编程中不被认为有用?
如果你想要了解螺母和螺栓,你可以使用原子整数和指针:
http://doc.qt.io/archives/qt-4.7/qatomicint.html
http://doc.qt.io/archives/qt-4.7/qatomicpointer.html
但你确实想要使用Qt的线程原语.与使用互斥锁,信号量和等待条件相比,旋转/睡眠是浪费的.这些是你在任何线程库中都能找到的相当一般的概念,所以我会四处寻找它们的好解释.一开始不是很容易把头包起来,但是需要知道它!
QWaitCondition的生产者/消费者示例应该说明您的场景:
http://doc.qt.io/qt-4.8/qt-threads-waitconditions-example.html