我对连续创建的线程的执行顺序有疑问。这是代码。
#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;
}
每次将一个字母(从 A 到 D)和一个genereaion id (i) 作为线程传递给 SomeWork 方法。我不关心字母之间的执行顺序,但对于一个特定的字母,比如 A,如果 x < y,Ax 必须在 Ay 之前开始。代码的随机输出的随机部分是:
B0 开始 D1 开始 C2 开始 A3开始 B0 完成 B12开始 D1 完成 D15 开始 C2完成 C6开始 A3成品 A9开始 B12完成 B11 开始 --> B11 在 B12 完成后开始。 D15完成 D13 开始 C6完成 C7开始 A9完成
怎样才能避免这种情况?
谢谢。
我使用条件变量解决了这个问题。但我稍微改变了问题。解决方案是跟踪 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;
}