1

私はこれらのpthreadsに不慣れです。数字をランダムに表示するのではなく、順番に表示するようにプログラムを書きました。そのためにpthrea_join()メソッドを使用しました。プログラムは次のとおりです。

int cnt=0,i=1;
pthread_t th[10];
int printmsg()
{
  cnt++;
  printf( "thread no. %d\n",cnt);
}
void tosync()
{
  if(i>0)
  pthread_join(th[i-1],NULL); // <---here i am blocking the previous thread..                         
  printmsg();
}
void main(void)
{
  pthread_create(&th[0], NULL,(void*)&tosync, NULL);
  for( i=1;i<10; i++){
    pthread_create(&th[i],NULL, (void*) &tosync, NULL);
  } 
  int y;
  for(int i=0; i<10; i++)
    pthread_join(th[i],NULL);
  return;
}

それでも私はランダムに数字を取得しています...plzz。ヘルプ

4

5 に答える 5

2

tosync各スレッドが待機する必要があるスレッドを認識できるように、ルーチンに何かを渡す必要があります。また、一番最初のスレッドは誰も待ってはいけません。スレッド開始ルーチンに適切な署名を使用する場合は、引数を渡すことができます。

void * tosync(void *arg)
{
  pthread_t *me = (pthread_t *)arg;
  if (me > th) pthread_join(me[-1],NULL);
  printmsg();
  return 0;
}

mainが返されintます。開始ルーチンがキャストを必要としなくなったため、ループが簡素化されました。各スレッドはすでに先行スレッドと結合しているため、mainスレッドは最後のスレッドと結合するだけで済みます。

int main(void)
{
  for( i=0;i<10; i++){
    pthread_create(&th[i],NULL, tosync, &th[i]);
  }
  pthread_join(th[9],NULL);
  return 0;
}
于 2012-08-11T18:28:17.540 に答える
1

別のアプローチ:

#include <stdio.h>
#include <pthread.h>

struct threadData{
    int id;
    pthread_t prev;
};


void tosync(void *data)
{
    struct threadData *td=data;
    if ((*td).prev!=0){
        printf("%i waiting\n",(*td).id);
        fflush(0);
        pthread_join((*td).prev,NULL); // <---here i am blocking the previous thread..                         
    }
    printf("%i runnning\n",(*td).id);
    fflush(0);
    free(td);
}

int main(void)
{
    int i;
    struct threadData *td;
    pthread_t nextThreadID=0;
    for( i=0;i<10; i++){
        td=malloc(sizeof(struct threadData));
        (*td).prev=nextThreadID;
        (*td).id=i;
        pthread_create(&nextThreadID,NULL, (void*) &tosync, (void *)td);
    } 
    pthread_join(nextThreadID,NULL);
    return 0;
}
于 2012-08-11T18:17:32.063 に答える
1

pthread_join(th[i-1],NULL) この行にはいくつかの問題があります。スレッドを作成するときは、i の値を作成します。最初の 3 つのスレッドを作成し、OS が 3 番目のスレッドの開始を切り替え、OS が残りのスレッドを作成するメインスレッドに切り替えるとします。すべてのスレッドを作成した後、i の値は 10 です。OS が 3 番目のスレッドに切り替わったと仮定すると、10-1 = 9 番目のスレッドが終了するまで待機し、同様に続行します。したがって、最終的には常にランダムに出力されます。あなたの戦略は間違っています。

これを試して

int cnt=0,i=1;
pthread_t th[10];
int printmsg()
{
cnt++;
printf( thread no. %d\n",cnt);
}
void tosync()
{

printmsg();
}
void main(void)
{
pthread_create(&th[0], NULL,(void*)&tosync, NULL);
for( i=1;i<10; i++){
pthread_create(&th[i],NULL, (void*) &tosync, NULL);
pthread_join(th[i],NULL); // <---here i am blocking the previous thread..   
} 

return;
}
于 2012-08-11T17:59:41.777 に答える
1

toSync値を使用している関数では、toSync 関数の実行時にiどのような値があるかわからないという問題があります。i

極端な場合、すべてのスレッドの値が 10 になる可能性があります。これは、作成されたスレッドが実行される前に、スレッドを作成するループが実行される場合に発生します。

iクリーンな解決策は、パラメーターとして値を渡し、 global の代わりにそれを使用できるようにすることpthread_createです。例えばtoSynci

int *id = (int*)malloc(sizeof(int));
*id = i;
pthread_create(&th[i],NULL, (void*) &tosync, id);

その他の考慮事項:

  1. toSync待機する先行スレッドがないため、ID 0 のスレッドには特別な処理が必要です
  2. スレッド 0 ~ 8 は既に結合されているため、最後のループをスレッド 0 ~ 8 でmain呼び出すべきではありません。同じスレッドで複数回pthread_join呼び出した結果は未定義ですpthread_join
于 2012-08-11T18:06:17.647 に答える
1

何が起こっているかというと、スレッドが実際に開始されたときの値を知る代わりに、tosync()メソッドがグローバル変数を使用しているということです。tosyncに (またはここでは前の pthread_t へのポインター) を渡して、どのスレッドに参加する必要があるかを実際に記憶させたい場合は、次のように pthread_create を介して渡す必要があります。iii

void* tosync(void* ptr)
{
  pthread_t* threadIndex = (pthread_t*)ptr;
  if(threadIndex != NULL)
      pthread_join(*threadIndex, NULL); // <---here i am blocking the previous thread..                         
  printmsg();
}

...in the loop...

pthread_create(&th[i], NULL, tosync, &th[i-1]);

これは、メソッドで threadIndex として渡される pthread_create の最後のパラメーターです。インデックスが含まれている場合、各スレッドは個別のインデックスを認識します。

于 2012-08-11T18:08:03.107 に答える