2017-02-16 112 views
0

这是我写的一个简单的程序。它创造了一个10个线程的循环和每个线程打印i的值:Pthread没有打印正确的值

#include <stdio.h> 
#include <pthread.h> 
void* basic_function(void *num){ 
    int cur_num = *(int*)num; 
    printf("Current thread number is :%d\n", cur_num); 
    return NULL; 
} 

int main(int argc, const char * argv[]) { 
    pthread_t thread_id [10]; 
    void * exit_status[10]; 

    for (int i = 0; i < 10; i++){ 
     pthread_create(&thread_id[i], NULL, basic_function, &i); 
     printf("i is: %d\n", i); 
    } 


    for (int i = 0; i<10; i++){ 
     pthread_join(thread_id[i], &exit_status[i]); 


    return 0; 
} 

我想输出应该看起来像一些打印语句从0到9,以正确的顺序:

Current thread number is: 0 
i is: 0 
Current thread number is: 1 
i is: 1 
Current thread number is: 2 
i is: 2 
... 

而是我的输出是:

i is: 0 
i is: 1 
i is: 2 
i is: 3 
i is: 4 
i is: 5 
Current thread number is: 6 
Current thread number is: 6 
i is: 6 
Current thread number is: 6 
Current thread number is: 6 
Current thread number is: 6 
Current thread number is: 6 
Current thread number is: 6 
i is: 7 
Current thread number is: 7 
i is: 8 
Current thread number is: 9 
Current thread number is: 9 
i is: 9 

为什么用线6创造了多次?为什么有些线程没有创建?还有,为什么我运行程序时总会得到不同的输出结果?

回答

1

因为传递给线程函数的参数指向相同的变量 - i

而作为变量i不断从main功能更新,螺纹总是在其运行的时间得到最新的值与线程做,在与main方法并行。此外,一旦循环已经完成,可能会发生线程访问变量,在这种情况下,它是未定义的行为。

解决方法是在堆上分配i的副本并将指针传递给副本。或者另一个更脏的解决方案是将i转换为指针,作为参数传递,然后在线程中转换回int。这依赖于int小于指针,这是相当普遍的,但在一些模糊的架构可能不是真实的(可能不是这样的小数字)。

+0

我明白你的第一个解决方案。但我不知道为什么将'i'指向指针可以解决问题。我认为它与'pthread_create(&thread_id [i],NULL,basic_function,&i)'有相同的效果,这是我在我的文章中所做的。 – HalfOfRain

+0

不,它没有相同的效果,因为投射到指针会创建指针所携带的整数的副本。不像Zbynek指出的那样便携,但如果可行的话可靠 – LWimsey