【发布时间】:2020-10-04 21:24:00
【问题描述】:
我有一个线程在等待来自不同数量的其他线程的某个事件,这取决于来自这个线程的事件来继续处理。如何编码以避免忙循环?
更具体地说,我有多个线程来处理它们各自的视频帧并将其写入屏幕缓冲区(在不同的位置)。全部完成后,一个线程发送缓冲区进行绘制,然后这些线程等待绘制调用完成,然后继续进行下一帧。
这需要在 C++ 中实现。使用的 C++ 标准不受限制。
编辑:std::condition_variable 似乎不是解决方案。由于它需要一个互斥体,并且线程(互斥体)的数量在运行时是已知的,我无法将互斥体放入std::vector
我的程序的伪代码是这样的:
drawThread:
loop:
for each processThread:
wait for event
draw()
processThread:
loop:
process()
notify drawThread
wait for draw to finish
编辑:我尝试了什么:
std::vector<std::atomic_bool> ready_flags;
std::atomic_bool finished_drawing = false;
void drawThread()
{
while(true)
{
CHECK:
for(auto& flag: ready_flags)
{
if(!flag)
goto CHECK;
}
draw();
finished_drawing = true;
}
}
void ProcessThread(int id)
{
while(true)
{
process();
finished_drawing=false;
ready_flags[id] = true;
while(!finished_drawing)
;
}
}
【问题讨论】:
-
std::condition_variable en.cppreference.com/w/cpp/thread/condition_variable
-
条件变量只需要一个互斥锁。没有法律规定每个线程必须始终使用自己的独占互斥锁。这样做实际上违背了互斥锁的目的,因为它们被明确设计为可由多个线程访问。毕竟,这就是互斥锁的全部意义所在。
-
互斥锁保护数据免受来自任意数量线程的并发访问。也就是说,您已经选择了工具(线程数、通信方法),现在您遇到了问题。但是,也许您更应该描述目标,另请参阅“XY 问题”。
-
你说你不能使用互斥体向量。其实you can,只是你需要通过适当的
reserve来避免重新分配。或者,如果您事先不知道线程/互斥体的数量,您可以使用互斥体的std::deque或std::list来代替。问题可能是,您不能一次等待多个条件变量。但是这个问题是可以解决的,例如,通过引入一些伴随单个条件变量的(无锁)事件队列。 -
@DanielLangr 你能根据我的情况详细说明一下吗?即使只是伪代码也值得赞赏。
标签: c++ multithreading