我认为我的问题很常见,但它让我发疯:
我有一个包含5个线程的多线程应用程序。其中4个线程完成它们的工作,比如网络通信和本地文件系统访问,然后所有线程都将它们的输出写入这种形式的数据结构:
struct Buffer {
std::vector<std::string> lines;
bool has_been_modified;
}
第5个线程将这些缓冲区/结构打印到屏幕上:
Buffer buf1, buf2, buf3, buf4;
...
if ( buf1.has_been_modified ||
buf2.has_been_modified ||
buf3.has_been_modified ||
buf4.has_been_modified )
{
redraw_screen_from_buffers();
}
如何保护缓冲区在被读取或写入时不会被覆盖?
我无法找到合适的解决方案,但我认为这必须是一个安静的常见问题。
感谢。
答案 0 :(得分:10)
您应该使用互斥锁。互斥类为 <Page.BottomAppBar>
<CommandBar IsTabStop="False" ClosedDisplayMode="Minimal">
<!-- Buttons -->
</CommandBar>
</Page.BottomAppBar>
。使用C ++ 11,您可以使用std::mutex
使用RAII封装互斥锁。因此,您可以将std::lock_guard<std::mutex>
结构更改为
Buffer
每当您读取或写入缓冲区或struct Buffer {
std::vector<std::string> lines;
bool has_been_modified;
std::mutex mutex;
};
时,您都会
has_been_modified
并且当std::lock_guard<std::mutex> lockGuard(Buffer.mutex); //Do this for each buffer you want to access
... //Access buffer here
被销毁时,互斥锁将自动释放。
您可以阅读有关互斥锁here的更多信息。
答案 1 :(得分:5)
您可以在缓冲区周围使用互斥锁(或互斥锁),以确保它们不会被多个线程同时修改。
// Mutex shared between the multiple threads
std::mutex g_BufferMutex;
void redraw_screen_from_buffers()
{
std::lock_guard<std::mutex> bufferLockGuard(g_BufferMutex);
//redraw here after mutex has been locked.
}
然后,在修改缓冲区时,您的缓冲区修改代码必须锁定相同的互斥锁。
void updateBuffer()
{
std::lock_guard<std::mutex> bufferLockGuard(g_BufferMutex);
// update here after mutex has been locked
}
This包含一些互斥示例。
答案 2 :(得分:3)
您想要完成的是拥有多个线程/工作人员和一个观察者。后者只有在所有工人完成/发出信号后才能完成工作。如果是这种情况,则检查此SO q / a中的代码。 std::condition_variable - Wait for several threads to notify observer
答案 3 :(得分:2)
通过锁定,您正在同步线程。因为只有一个一次可以访问向量,在线程写入容器将导致另一个等待它完成...可能对你有好处,但是当需要高性能时会导致严重的性能。 / p>
最好的解决方案是使用更复杂的无锁结构。不幸的是,我认为STL中没有任何标准的无锁结构。可以使用无锁队列的一个例子here
使用这样的结构,你的4个工作线程将能够将消息排入容器,而第5个将使它们出列,而没有任何数据集