【发布时间】:2012-07-04 21:14:17
【问题描述】:
我以前就这个话题发过帖子,但到目前为止我还没有运气。我把它归结为我的一个坏问题。这次我做了一个简短的可编译示例,显示了我试图避免的不良行为。我希望这会受到赞赏。
问题是两个(或更多)线程被设置为运行同一个进程,它们的“id”决定了它们操作变量数据的哪一部分。目前两个线程都会更新计数器。
当前的输出是这样的,
tid = 0, var[tid] = 0
tid = 0, var[tid] = 1
tid = 0, var[tid] = 2
tid = 0, var[tid] = 3
tid = 0, var[tid] = 4
tid = 0, var[tid] = 5
tid = 0, var[tid] = 6
tid = 0, var[tid] = 7
tid = 0, var[tid] = 8
tid = 0, var[tid] = 9
tid = 1, var[tid] = 0
Press any key to continue . . .
想要的输出应该是这样的……
tid = 0, var[tid] = 0
tid = 1, var[tid] = 0
tid = 0, var[tid] = 1
tid = 1, var[tid] = 1
tid = 0, var[tid] = 2
tid = 1, var[tid] = 2
tid = 0, var[tid] = 3
tid = 1, var[tid] = 3 etc.
我们将不胜感激任何指导。
编辑:我已经使用按预期工作的代码更新了答案。
[注意这里效率很重要,我想尽快完成流程]
#include <iostream>
#include <boost/thread.hpp>
int var[2];
int mT;
int mTotalSamples;
boost::mutex mCountMutex;
boost::thread *threadMap[2];
using namespace std;
void process()
{
int tid = 1;
// sleep for 1 seconds - just to make sure threadMap
// has been assigned (only ncessary for this demo).
boost::this_thread::sleep(boost::posix_time::seconds(1));
if (threadMap[0]->get_id() == boost::this_thread::get_id()){ tid = 0;}
while ( mT < mTotalSamples )
{
// perform processing
var[tid] = mT;
// processing complete
mCountMutex.lock(); // (a thread waits to aquire mutex)
cout << "tid = " << tid << ", var[tid] = " << var[tid] << endl;
mT++; // How to stop both threads incrementing this?
mCountMutex.unlock();
}
}
int main()
{
boost::thread_group threads;
mT = 0;
mTotalSamples = 10;
threadMap[0] = threads.create_thread( boost::bind(&process) );
threadMap[1] = threads.create_thread( boost::bind(&process) );
threads.join_all();
return 0;
}
【问题讨论】:
-
听起来您希望线程能够交错访问互斥锁。但是您的代码中没有任何内容可以强制执行此操作。如果您希望操作以特定顺序开始,那么线程可能不是解决方案...
-
@OliCharlesworth 互斥锁不是问题,每个线程应该只执行一行,var[tid] = mT;当计数器增加一次时。但是,老实说,我认为使用 cout 可能会混淆问题。
-
为了保护计数器,您可以使用互锁操作,例如 Windows 上的
LONG __cdecl InterlockedIncrement( LONG volatile *Addend );。你真的需要保护你的var变量吗? -
尝试安排两个线程相互协作并没有多大意义,您不妨忘记线程,只需按程序/手动安排操作。在切换到另一个线程之前,线程会被赋予一定的执行时间。在那个时候,线程可能会完成比您想要的更多的工作,并且强制一个线程让步给另一个线程可能会影响调度程序的效率,从而影响您的应用程序的整体性能。您应该真正考虑是否需要线程来实现您的目的。也许他们是,也许不是,但请考虑一下
-
@dreamlax 谢谢,我知道这个例子有点做作,因为我为了使问题易于理解而进行了简化。实际上,一个线程可能需要几秒钟的时间,实际上我会执行与内核一样多的线程,并在这些线程之间平均分配“var”的更新,从而减少完成一个循环的时间.线程绝对适用于此目的。
标签: c++ multithreading boost boost-thread