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 为非负数时,2​​ + N 永远不会为 0 以执行 0 到 99999 的迭代。

于 2013-06-24T15:44:11.563 回答
1

我认为您对线程是什么感到困惑。将每个线程视为自己的程序。如果您同时运行 10 个程序,它们将“同时”运行,即这 10 个程序的指令将被交错,但在每个程序中,所有指令都以确定的顺序执行。线程也是一样。您可以通过在创建线程时传递线程 id 参数来定义每个线程将迭代的数字。

于 2013-06-24T15:45:27.710 回答
0

您正在将变量的地址发送到线程tids[i]i基于它进行打印。在这种情况下,线程将始终从 until 打印NN000000所有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在没有任何类型的锁定机制的情况下,使用在线程之间共享的全局变量(如 )是不明智的。他们会带来意想不到的结果。使用pthread_mutex 这里可以解决这个问题。

于 2013-06-24T15:54:46.610 回答