我是多线程编程的新手,我对“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完成的?
答案 0 :(得分:2)
这是因为迭代范围是根据以下行中从0到N的线程数计算的:
start = (*mytid * ITERATIONS);
您可以在循环中创建并传递该数字:
for (i=0; i<NTHREADS; i++) {
tids[i] = i;
...
换句话说,当N为非负数时,2 + N将永远不会为0,从而在0到99999之间执行迭代。
答案 1 :(得分:1)
我认为你对于什么线程感到困惑。 将每个线程视为自己的程序。如果你同时运行10个程序,它们将“同时”运行,即这10个程序的指令将被交错,但在每个程序中,所有指令都以确定的顺序执行。 线程也一样。您可以通过在创建线程时传递线程id参数来定义每个线程将迭代的数字。
答案 2 :(得分:0)
您正在将tids[i]
th 变量的地址发送给线程i
并根据它进行打印。在这种情况下,N
th 主题将始终从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
因此将2000000
打印到2999999
。因此,您不能指望thread 2
打印0 to 99999
。
使用像sum
之类的全局变量是明智的,它们在线程之间共享,没有任何类型的锁定机制。他们会带来意想不到的结果在这里使用pthread_mutex
可以解决这个问题。