ali*_*hoo 5 c++ multithreading boost mutex boost-thread
我对连续创建的线程的执行顺序有疑问.这是代码.
#include <iostream>
#include <Windows.h>
#include <boost/thread.hpp>
using namespace std;
boost::mutex mutexA;
boost::mutex mutexB;
boost::mutex mutexC;
boost::mutex mutexD;
void SomeWork(char letter, int index)
{
boost::mutex::scoped_lock lock;
switch(letter)
{
case 'A' : lock = boost::mutex::scoped_lock(mutexA); break;
case 'B' : lock = boost::mutex::scoped_lock(mutexB); break;
case 'C' : lock = boost::mutex::scoped_lock(mutexC); break;
case 'D' : lock = boost::mutex::scoped_lock(mutexD); break;
}
cout << letter <<index << " started" << endl;
Sleep(800);
cout << letter<<index << " finished" << endl;
}
int main(int argc , char * argv[])
{
for(int i = 0; i < 16; i++)
{
char x = rand() % 4 + 65;
boost::thread tha = boost::thread(SomeWork,x,i);
Sleep(10);
}
Sleep(6000);
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每次将一个字母(从A到D)和一个genereaion id(i)传递给方法SomeWork作为一个线程.我不关心字母之间的执行顺序,但对于一个特殊的字母,比如A,Ax必须在Ay之前开始,如果x <y.随机输出代码的随机部分是:
B0 started D1 started C2 started A3 started B0 finished B12 started D1 finished D15 started C2 finished C6 started A3 finished A9 started B12 finished B11 started --> B11 started after B12 finished. D15 finished D13 started C6 finished C7 started A9 finished
怎么能避免这种情况?
谢谢.
我使用条件变量解决了问题.但我改变了一点问题.解决方案是跟踪for循环的索引.所以每个线程都知道什么时候不起作用.但就这段代码而言,还有两件我想问的问题.
首先,在我的计算机上,当我将for循环索引设置为350时,我有一个访问冲突.310是循环次数,这没关系.所以我意识到要生成最大数量的线程.我怎么能确定这个数字?第二,在visual studio 2008中,代码的发布版本显示了一种非常奇怪的行为.不使用条件变量(第1行到第3行被注释掉),线程被排序.怎么会发生这种情况?
这是代码:
#include <iostream>
#include <Windows.h>
#include <boost/thread.hpp>
using namespace std;
boost::mutex mutexA;
boost::mutex mutexB;
boost::mutex mutexC;
boost::mutex mutexD;
class cl
{
public:
boost::condition_variable con;
boost::mutex mutex_cl;
char Letter;
int num;
cl(char letter) : Letter(letter) , num(0)
{
}
void doWork( int index, int tracknum)
{
boost::unique_lock<boost::mutex> lock(mutex_cl);
while(num != tracknum) // line 1
con.wait(lock); // line 2
Sleep(10);
num = index;
cout << Letter<<index << endl;
con.notify_all(); // line 3
}
};
int main(int argc , char * argv[])
{
cl A('A');
cl B('B');
cl C('C');
cl D('D');
for(int i = 0; i < 100; i++)
{
boost::thread(&cl::doWork,&A,i+1,i);
boost::thread(&cl::doWork,&B,i+1,i);
boost::thread(&cl::doWork,&C,i+1,i);
boost::thread(&cl::doWork,&D,i+1,i);
}
cout << "************************************************************************" << endl;
Sleep(6000);
system("PAUSE");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果你有两个不同的线程在等待锁定,那么一旦前一个持有者释放锁定,它将完全不确定.我相信这正是你所经历的.假设B10持有锁,并且平均时间产生线程B11和B12. B10解除锁定-这是到抛硬币是否B11或B12获得其未来,无论哪个线程首先被创造,甚至是哪个线程首先开始等待.
也许你应该为每个字母实现工作队列,这样你就会产生4个线程,每个线程都消耗工作单元?这是以这种方式轻松保证订购的唯一方法.如果多个线程正在等待锁定,则简单的互斥锁不会保证排序.