Ale*_*exS 1 c++ algorithm multithreading boost boost-thread
例如,我有一些由多个线程同时计算的工作.
出于演示目的,工作在while循环内执行.在单次迭代中,每个线程执行其自己的工作部分,在下一次迭代开始之前,计数器应该递增一次.
我的问题是每个线程都会更新计数器.
由于这似乎是一件相对简单的事情,我认为有一种"最佳实践"或常用方法可以解决这个问题?
下面是一些示例代码来说明问题并帮助讨论.(我使用提升线程)
class someTask {
public:
int mCounter; //initialized to 0
int mTotal; //initialized to i.e. 100000
boost::mutex cntmutex;
int getCount()
{
boost::mutex::scoped_lock lock( cntmutex );
return mCount;
}
void process( int thread_id, int numThreads )
{
while ( getCount() < mTotal )
{
// The main task is performed here and is divided
// into sub-tasks based on the thread_id and numThreads
// Wait for all thread to get to this point
cntmutex.lock();
mCounter++; // < ---- how to ensure this is only updated once?
cntmutex.unlock();
}
}
};
Run Code Online (Sandbox Code Playgroud)
我在这里看到的主要问题是你的理由太低了.因此,我将提出一个基于新的C++ 11线程API的替代解决方案.
主要的想法是你基本上有一个时间表 - > dispatch - > do - > collect - >循环例程.在你的例子中,你试图在do阶段内对所有这些进行推理是非常困难的.使用相反的方法可以更容易地表达您的模式.
首先,我们将要完成的工作隔离在自己的例行程序中:
void process_thread(size_t id, size_t numThreads) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以轻松调用此例程:
#include <future>
#include <thread>
#include <vector>
void process(size_t const total, size_t const numThreads) {
for (size_t count = 0; count != total; ++count) {
std::vector< std::future<void> > results;
// Create all threads, launch the work!
for (size_t id = 0; id != numThreads; ++id) {
results.push_back(std::async(process_thread, id, numThreads));
}
// The destruction of `std::future`
// requires waiting for the task to complete (*)
}
}
Run Code Online (Sandbox Code Playgroud)
(*)看到这个问题.
你可以std::async 在这里阅读更多,这里提供一个简短的介绍(它们似乎与发布政策的效果有些矛盾,哦).这里更简单的是让实现决定是否创建OS线程:它可以根据可用内核的数量进行调整.
请注意如何通过删除共享状态来简化代码.因为线程没有共享,我们不再需要明确地担心同步!