Strange behavior when functions created in pthread_create accept pointer-to-int

蹲街弑〆低调 提交于 2020-04-18 03:47:38

问题


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

void *runner(void * p)
{
    int *line = p;
    printf("line: %d\n", *line);
}
int main()
{
    pthread_t tid[2];                                                                                                       
    for (int i = 0; i < 2; i++)
        pthread_create(&tid[i], 0, runner, &i);
    for (int i = 0; i < 2; i++)                                                                                                       
        pthread_join(tid[i], NULL);
    return 0;
}

For the above code I expect the output to be

line 0
line 1

But the output is actually

line 1
line 2

So what is wrong with this code? How did i get incremented? Do I have to pass structs to the runner function?


回答1:


There's no guarantee that printf("line: %d\n", *line); line will finish before pthread_create returns, which means you have a race on i. (The main thread tries to increment it and the new threads try to read it via their argument pointer).

You can solve the problem by passing pointers to different objects (one per thread, optimally cache-aligned, but that hardly matters here):

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

void *runner(void * p)
{
    int *line = p;
    printf("line: %d\n", *line);
    return 0;
}
int main()
{
    pthread_t tid[2];
    int ints[2];
    for (int i = 0; i < 2; i++){
        ints[i]=i;
        if(pthread_create(&tid[i], 0, runner, &ints[i])) return 1;
    }
    for (int i = 0; i < 2; i++)
        pthread_join(tid[i], NULL);
    return 0;
}

or by passing the i by value (by casting it to void*):

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

void *runner(void * p)
{
    printf("line: %d\n", (int)(intptr_t)p);
    return 0;
}
int main()
{
    pthread_t tid[2];
    int ints[2];
    for (int i = 0; i < 2; i++){
        if(pthread_create(&tid[i], 0, runner, (void*)(intptr_t)i)) return 1;
    }
    for (int i = 0; i < 2; i++)
        pthread_join(tid[i], NULL);
    return 0;
}


来源:https://stackoverflow.com/questions/60828040/strange-behavior-when-functions-created-in-pthread-create-accept-pointer-to-int

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!