2

VS.NET2003のプログラムで問題が発生しています。

私は最初、pthreadライブラリを使用して、何かを処理するための多数のスレッドを作成するモジュールを作成しました。これはVS.NET2003で正しく実行されます。その後、このモジュールは他の誰かによって使用され、別のより大きなプログラムに統合されました。詳細はわかりませんが、プログラムは、ユーザーがモジュールを実行するためのオプションを選択できるGUIを作成します。

スレッドが作成されると、値がスレッドIDとして渡されます。GUIのモジュールの問題は、すべてのスレッドでスレッドIDの値が0であるのに対し、GUIのない​​モジュールではスレッドIDが正しいことです。

モジュールでスレッドが作成される方法は次のとおりです。

int64_t *tid[1000];
int64_t i = 0, rc;

for (i = 0 ; i < NUM_THREADS ; i++)
{
   tid[i] = (int64_t *) malloc(sizeof(int64_t));
   *tid[i] = i;
   rc = pthread_create(&pthread, &attr, function, (void *)tid[i]);
   Sleep(1);
   if(rc)
   {
      free(tid[i]);
      exit(1);
   }
   free(tid[i]);
}

両方のプロジェクトプロパティを確認しました。2つのプロジェクトの違いは次のとおりです。

GUI - use managed extensions | my module (w/o GUI) - does not use managed extensions
In C/C++ preprocessor:
   GUI - WIN32;_DEBUG;_CONSOLE;WINDOWS | my module (w/o GUI) - none
In C/C++ Additional Options:
   GUI - /CLR | my module (w/o GUI) - no /CLR (error with /CLR: fatal error LNK1000: Internal error during BuildImage)

コードは同じなので、マネージド拡張機能/ clrの使用が何らかの違いをもたらさない限り、GUIの出力が間違っている理由がわかりません。(どちらかはよくわかりません。)

スレッドIDを出力するコードの一部を追加するために編集されました。

void *function(void *input)
{
   int64_t threadid = *(int64_t *)input;
   printf("threadid = %ld\n", threadid);
   ...
}

お知らせ下さい。

ありがとうございました。

よろしく、レイン

4

1 に答える 1

0

関数にtidを渡すときに競合状態が発生しているようです。代わりに、Sleep(1)を削除して、スレッドフリーのtidを試してください。上記のコメントから、これで問題が解決したようです。

他の質問に答えるために、pthread_createがメインスレッドに戻ると、新しいスレッドが作成されています(OSのスレッドに割り当てられたメモリなど)が、実際にはまだ実行されていない可能性があります。Sleep(1)を置くと、新しいスレッドが実行される可能性が高くなります(メインスレッドにタイムスライスを強制的に放棄させます)が、メインスレッドが再度実行されてfree(tid [i])を呼び出す前にスレッドがtidを取得する保証はありません。

したがって、ワーカースレッドを解放するというアイデアは、それを取得した後に解放されます。

tid配列をint64の配列に変更し、&tid [i]を渡すと、malloc / freeは不要になり、競合状態も解決されます。ただし、これは、呼び出し元が1人だけであることが保証されている場合にのみ機能します。一度にライブラリ。

これがお役に立てば幸いです。スレッドを正しく作成するのは難しいかもしれませんが、努力する価値は十分にあります。

于 2010-03-03T12:19:52.727 に答える