2

前の質問が閉じられたので、これを再投稿します..今回はもっとよく説明しようとしました...さらに説明が必要な場合はお知らせください:

関数 doSomething(int count) を持つクラス A があります クラス A 内で、それぞれ関数 doSomething() を呼び出し、各スレッドでカウント 1 ~ 100 を渡す 100 のスレッドを開きたいと考えています。

つまり...最初のスレッドがこの関数を呼び出すとき、それはdoSomething(1)を呼び出す必要があり、2番目のスレッドはdoSomething(2)を呼び出す必要があります...

これは私のコードがどのように見えるかです:

struct input {
  A* in;
  int count;
};


myFunc(void* data)
{
  input* tP = (input*) data;
  A* obj = tP->in;
  int ct = tP->count;
  obj->doSomething(ct);
}

class A {
  doSomething(int count);
  Thread2doSomething();
}

doSomething(int count)
{
  cout<<"Print value is"<<count;
}

Thread2doSomething()
{
   for (i = 1 to 100)
   {
      input myIN;
      myIN.in = this;
      myIN.count = i;
      beginthreadex(myFunc, &myIN);
   }
 }

上記のコードは、ここで 100 個のスレッドを生成することを期待しています..doSomething(); を呼び出すと、それぞれのスレッドの新しい値は count 1,2,3...100 になります。

新しいスレッドでの doSomething の呼び出しごとに、1、2、3、... から 100 までの異なるカウント値が渡される必要があります。

しかし、そうはなりません。それに渡されるカウント値はかなりランダムです...しばしば同じ値を複数回取得します...そしていくつかの値をまったく取得しません.時々doSomethingに渡されるカウントの値はすべてのスレッドで同じです...

呼び出しは、doSOmething(4)、doSomething(4)、doSomething(7)、doSomething(10)、doSomething(10) などのようになります。

私が物事を明確にしたことを願っています... plsはアドバイスします。

4

2 に答える 2

2

コードには2つの問題があります。

最初の問題はThread2doSomething()関数にあります。一時的なアドレスをに渡しますbeginthreadex()。関数が終了すると一時はスコープ外になり、スレッドはもう存在しないオブジェクトにアクセスしています。

これを修正するには、2つの可能性があります。すべてのスレッドが完了するのを待ってから終了するか、Thread2DoSomething()スレッドがジョブを完了する前にスタックに割り当てられたオブジェクトが破棄されないようにするか、各スレッドの入力をに割り当てます。ヒープ(ただし、生のポインターを使用する場合は、それらの割り当てを解除することを忘れないでください)。

2番目の問題は、すべてのスレッドに同じ入力を渡し、スレッドがアクセスしている間にforループ内で)それを変更することです。これにより、データの競合が発生します。このため、プログラムの動作は未定義です。

inputこれを修正するには、スレッドごとにの新しいインスタンスを作成する必要があります。これにより、スレッドがアクセスしようとしているときに同じオブジェクトが上書きされないようになります。

最後に、スレッドの実行順序については保証されないことに注意してください。特定の順序で開始した場合でも、順序付けられたシーケンス1..100ではなく、番号の順列が出力される場合があります。

于 2013-01-17T08:51:40.493 に答える
0

すべてのスレッドに対しての1つのインスタンスを再利用しています。inputもちろん、彼らはそこからランダムなデータを取得します。の署名を変更することはできないためmyFunc()(スレッド作成関数によって義務付けられていると思います)、動的割り当てを使用する必要があります。

Thread2doSomething()
{
   input *myIN;
   for (i = 1 to 100) {
     myIN = new input;
     myIN->in = this;
     myIN->count = i;
     beginthreadex(myFunc, myIN);
   }
}

myFunc(void* data)
{
  std::unique_ptr<input> tP(reinterpret_cast<input*>(data));
  A* obj = tP->in;
  int ct = tP->count;
  obj->doSomething(ct);
}

unique_ptrinを使用すると、終了myFunc()時にオブジェクトの割り当てが解除されmyFunc()ます。

于 2013-01-17T08:50:33.873 に答える