作为引用传递的变量的值在线程中发生更改
Value of the variable passed as reference gets changed in threads
我写这个小程序是为了理解 pthread_create 和 pthread_join 但我不明白为什么变量 data
的值在 thread_join 之后被改变了。它在调用 pthread 函数后打印为 0。
#include <pthread.h>
#include <stdio.h>
void* compute_prime (void* arg)
{
int n = *((int*) arg);
printf("Argument passed is %d\n",n);
return (void *)n;
}
int main ()
{
pthread_t thread;
int data = 5000;
int value=0;
pthread_create (&thread, NULL, &compute_prime, &data);
pthread_join (thread, (void*) &value);
printf("The number is %d and return value is %d.\n", data, value);
return 0;
}
输出为
Argument passed is 5000
The number is 0 and return value is 5000.
这是因为pthread_join
有原型void **
。它需要一个指向 void *
类型对象的 指针 ;它修改了这个 void *
对象。现在碰巧你在 64 位架构上 运行,其中 data
和 value
都是 32 位,并按顺序排列在内存中。修改内存中从 int
对象 value
地址开始布局的 void *
对象也会破坏 int
对象 data
,因为它们都是32 位 - 因此您会看到 data
被覆盖了。但是,这是未定义的行为,因此任何事情都可能发生。
不要使用转换,因为它们只会隐藏问题。转换为 void *
特别危险,因为 void *
可以隐式转换为任何其他类型,甚至转换为 void **
,尽管通常它也是不正确的。如果您删除演员表,您很可能会收到警告或类似
的错误
thrtest.c: In function ‘main’:
thrtest.c:16:31: error: passing argument 2 of ‘pthread_join’ from
incompatible pointer type [-Werror=incompatible-pointer-types]
pthread_join (thread, &value);
如果在启用警告的情况下进行编译。
但是如果你真的想这样做,你必须这样做:
void *value;
pthread_join(thread, &value);
intptr_t value_as_int = (intptr_t)value;
虽然它也不是真正可移植的,因为转换是实现定义的。
return 整数最便携的方法是 return 指向 malloc
对象的指针:
int *return_value = malloc(sizeof (int));
*return_value = 42;
return return_value;
...
void *value;
pthread_join(thread, &value);
int actual = *(int *)value;
free(value);
我写这个小程序是为了理解 pthread_create 和 pthread_join 但我不明白为什么变量 data
的值在 thread_join 之后被改变了。它在调用 pthread 函数后打印为 0。
#include <pthread.h>
#include <stdio.h>
void* compute_prime (void* arg)
{
int n = *((int*) arg);
printf("Argument passed is %d\n",n);
return (void *)n;
}
int main ()
{
pthread_t thread;
int data = 5000;
int value=0;
pthread_create (&thread, NULL, &compute_prime, &data);
pthread_join (thread, (void*) &value);
printf("The number is %d and return value is %d.\n", data, value);
return 0;
}
输出为
Argument passed is 5000
The number is 0 and return value is 5000.
这是因为pthread_join
有原型void **
。它需要一个指向 void *
类型对象的 指针 ;它修改了这个 void *
对象。现在碰巧你在 64 位架构上 运行,其中 data
和 value
都是 32 位,并按顺序排列在内存中。修改内存中从 int
对象 value
地址开始布局的 void *
对象也会破坏 int
对象 data
,因为它们都是32 位 - 因此您会看到 data
被覆盖了。但是,这是未定义的行为,因此任何事情都可能发生。
不要使用转换,因为它们只会隐藏问题。转换为 void *
特别危险,因为 void *
可以隐式转换为任何其他类型,甚至转换为 void **
,尽管通常它也是不正确的。如果您删除演员表,您很可能会收到警告或类似
thrtest.c: In function ‘main’:
thrtest.c:16:31: error: passing argument 2 of ‘pthread_join’ from
incompatible pointer type [-Werror=incompatible-pointer-types]
pthread_join (thread, &value);
如果在启用警告的情况下进行编译。
但是如果你真的想这样做,你必须这样做:
void *value;
pthread_join(thread, &value);
intptr_t value_as_int = (intptr_t)value;
虽然它也不是真正可移植的,因为转换是实现定义的。
return 整数最便携的方法是 return 指向 malloc
对象的指针:
int *return_value = malloc(sizeof (int));
*return_value = 42;
return return_value;
...
void *value;
pthread_join(thread, &value);
int actual = *(int *)value;
free(value);