連続して作成されたスレッドの実行順序に問題があります。これがコードです。
#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) と生成 ID (i) がメソッド SomeWork にスレッドとして渡されるたびに。文字間の実行順序は気にしませんが、特定の文字、たとえば A の場合、x < y の場合、Ax は Ay の前に開始する必要があります。コードのランダム出力のランダム部分は次のとおりです。
B0開始 D1開始 C2開始 A3開始 B0終了 B12開始 D1終了 D15開始 C2終了 C6始めました A3終了 A9開始 B12完成 B11 開始 --> B12 終了後に B11 開始。 D15終了 D13開始 C6完成 C7始めました A9終了
どうすればそのような状態を避けることができますか?
ありがとう。
条件変数を使用して問題を解決しました。しかし、私は問題を少し変えました。解決策は、for ループのインデックスを追跡することです。そのため、各スレッドはいつ機能しないかを知っています。しかし、このコードに関する限り、他に 2 点お聞きしたいことがあります。
まず、私のコンピューターで for-loop インデックスを 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;
}