0

私はマルチスレッドプログラミングが初めてで、「pthread_create」の動作について質問があります。これはコードです:

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

#define NTHREADS      10
#define ARRAYSIZE   1000000
#define ITERATIONS   ARRAYSIZE / NTHREADS

double  sum=0.0, a[ARRAYSIZE];
pthread_mutex_t sum_mutex;


void *do_work(void *tid) 
{
  int i, k=0,start, *mytid, end;
  double mysum=0.0;

  mytid = (int *) tid;
  start = (*mytid * ITERATIONS);
  end = start + ITERATIONS;
  printf ("Thread %d doing iterations %d to %d\n",*mytid,start,end-1);  
  for (i=start; i < end ; i++) {
    a[i] = i * 1.0;
    mysum = mysum + a[i];
    }

  sum = sum + mysum;

}


int main(int argc, char *argv[])
{
  int i, start, tids[NTHREADS];
  pthread_t threads[NTHREADS];
  pthread_attr_t attr;

  for (i=0; i<NTHREADS; i++) {
    tids[i] = i;
    pthread_create(&threads[i], NULL/*&attr*/, do_work, (void *) &tids[i]);
   }

  /* Wait for all threads to complete then print global sum */ 
/*
  for (i=0; i<NTHREADS; i++) {
    pthread_join(threads[i], NULL);
  }*/
  printf ("Done. Sum= %e \n", sum);

  sum=0.0;
  for (i=0;i<ARRAYSIZE;i++){ 
  a[i] = i*1.0;
  sum = sum + a[i]; }
  printf("Check Sum= %e\n",sum);

}

実行結果は次のとおりです。

Thread 1 doing iterations 100000 to 199999
Done. Sum= 0.000000e+00 
Thread 0 doing iterations 0 to 99999
Thread 2 doing iterations 200000 to 299999
Thread 3 doing iterations 300000 to 399999
Thread 8 doing iterations 800000 to 899999
Thread 4 doing iterations 400000 to 499999
Thread 5 doing iterations 500000 to 599999
Thread 9 doing iterations 900000 to 999999
Thread 7 doing iterations 700000 to 799999
Thread 6 doing iterations 600000 to 699999
Check Sum= 8.299952e+11

すべてのスレッドが作成され、実行はシーケンシャルではありませんが (pthread_join を削除)、関数 do_work は順番に実行され、スレッドに依存します。これは、0 から 99999 までの反復がスレッド 0 によって実行され、100000 から 199999 までの反復がスレッド 1 によって実行されることを意味します。

問題は、たとえば、0 から 99999 までの反復がスレッド 2 によって行われないのはなぜですか?

4

3 に答える 3

2

これは、反復範囲が次の行の 0 から N までのスレッド番号に基づいて計算されるためです。

start = (*mytid * ITERATIONS);

そして、その番号を次のようにループで作成して渡します。

for (i=0; i<NTHREADS; i++) {
    tids[i] = i;
    ...

つまり、N が非負の場合、0 から 99999 まで反復を実行するために、2 + N が 0 になることはありません。

于 2013-06-24T15:44:11.563 に答える
0

tids[i]th変数のアドレスをスレッドに送信し、iそれに基づいて印刷しています。この場合、スレッドは、すべての試運転で変更を加えることなく、常にN最後N000000まで印刷されます。N999999

mytid = (int *) tid;
start = (*mytid * ITERATIONS);
end = start + ITERATIONS;

スレッド 2 の場合、次のように動作します。

mytid = (int *) tid;                    // *mytid = 2
start = ( 2 * ITERATIONS);              // 2000000
end = ( 2 * ITERATIONS) + ITERATIONS;   // 2999999

したがって、に印刷20000002999999ます。thread 2したがって、印刷は期待できません0 to 99999


sumスレッド間で共有される のようなグローバル変数を、いかなる種類のロック機構もなしに使用するのは賢明ではありません。それらは予期しない結果をもたらすでしょう。here を使用すると、pthread_mutex この問題が解決します。

于 2013-06-24T15:54:46.610 に答える