在 pthread_create 中创建的函数接受指向 int 的指针时的奇怪行为
Strange behavior when functions created in pthread_create accept pointer-to-int
#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;
}
对于上面的代码,我希望输出为
line 0
line 1
但输出实际上是
line 1
line 2
那么这段代码有什么问题呢? i
是如何递增的?我必须将 struct
s 传递给 runner 函数吗?
无法保证 printf("line: %d\n", *line);
行会在 pthread_create
returns 之前完成,这意味着您在 i
上有一场比赛。
(主线程尝试增加它,新线程尝试读取它
通过他们的参数指针)。
您可以通过传递指向不同对象的指针来解决问题(每个线程一个,最佳缓存对齐,但这在这里并不重要):
#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;
}
或按值传递 i
(将其转换为 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;
}
#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;
}
对于上面的代码,我希望输出为
line 0
line 1
但输出实际上是
line 1
line 2
那么这段代码有什么问题呢? i
是如何递增的?我必须将 struct
s 传递给 runner 函数吗?
无法保证 printf("line: %d\n", *line);
行会在 pthread_create
returns 之前完成,这意味着您在 i
上有一场比赛。
(主线程尝试增加它,新线程尝试读取它
通过他们的参数指针)。
您可以通过传递指向不同对象的指针来解决问题(每个线程一个,最佳缓存对齐,但这在这里并不重要):
#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;
}
或按值传递 i
(将其转换为 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;
}