只有从线程返回的第一个值是错误的 (C)
Only first value returned from thread is wrong (C)
所以我在做 C 编程作业时遇到了线程的奇怪行为:
我给一个线程一个值,它把它返回给一个 pthread_exit()
函数,然后我在主函数中添加所有返回值。问题是只有第一个值是完全错误的,这意味着我的转换是正确的,但是有一个内存问题,即使有帮助我也没有设法解决。
代码如下:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void * fonction_thread(void * arg);
long s = 0; //int to sum on
int main (int argc, char* argv[])
{
int N,i ; //N is the number of threads created
void* ret ; //returned value
N= atoi(argv[1]);
s=0;
for(i=1; i<N+1; i++){
//creation of the threads
pthread_t thr;
if (pthread_create(&thr, NULL, fonction_thread, &i) != 0) {
fprintf(stderr, "Erreur dans pthread_create\n");
exit(EXIT_FAILURE);
}
//recovering the value
pthread_join(thr, &ret);
printf("retour : %d\n\n", *((int*)ret)); //transtyping void* to int* before derefencement
s+= *((int*)ret);
}
printf("%ld\n", s);
}
//thread handler
void * fonction_thread(void * arg)
{
int n;
n = *((int *)arg); //recovering the value given by the main
printf("thread numéro %d créé\n", n);
pthread_exit((void*) &n); //casting then returning value
}
这是控制台视图:
console screeshot
一个主要问题是您return指向本地变量的指针n
。
一旦fonction_thread
退出,所有局部变量的生命周期结束,任何指向它们的指针都将失效。
对于这样的事情,将值转换为指针并再次转换回来被认为是可以的(勉强),这意味着您可以对 return 值执行这样的操作:
return (void *) (intptr_t) n; // Or use pthread_exit((void *) (intptr_t) n)
然后当你收到“指针”时你做相反的转换:
int n = (int) (intptr_t) ret;
注意需要将i
的值传递给线程,方法相同。不是因为生命周期问题,而是因为所有线程都有完全相同的指针,并且会发生数据争用以获取值,这意味着多个线程似乎可以获得相同的值。
所以当你创建线程时传递值:
pthread_create(&thr, NULL, fonction_thread, (void *) (intptr_t) i)
并在函数中进行相反的转换以获取值:
int n = (int) (intptr_t) arg;
所以我在做 C 编程作业时遇到了线程的奇怪行为:
我给一个线程一个值,它把它返回给一个 pthread_exit()
函数,然后我在主函数中添加所有返回值。问题是只有第一个值是完全错误的,这意味着我的转换是正确的,但是有一个内存问题,即使有帮助我也没有设法解决。
代码如下:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void * fonction_thread(void * arg);
long s = 0; //int to sum on
int main (int argc, char* argv[])
{
int N,i ; //N is the number of threads created
void* ret ; //returned value
N= atoi(argv[1]);
s=0;
for(i=1; i<N+1; i++){
//creation of the threads
pthread_t thr;
if (pthread_create(&thr, NULL, fonction_thread, &i) != 0) {
fprintf(stderr, "Erreur dans pthread_create\n");
exit(EXIT_FAILURE);
}
//recovering the value
pthread_join(thr, &ret);
printf("retour : %d\n\n", *((int*)ret)); //transtyping void* to int* before derefencement
s+= *((int*)ret);
}
printf("%ld\n", s);
}
//thread handler
void * fonction_thread(void * arg)
{
int n;
n = *((int *)arg); //recovering the value given by the main
printf("thread numéro %d créé\n", n);
pthread_exit((void*) &n); //casting then returning value
}
这是控制台视图: console screeshot
一个主要问题是您return指向本地变量的指针n
。
一旦fonction_thread
退出,所有局部变量的生命周期结束,任何指向它们的指针都将失效。
对于这样的事情,将值转换为指针并再次转换回来被认为是可以的(勉强),这意味着您可以对 return 值执行这样的操作:
return (void *) (intptr_t) n; // Or use pthread_exit((void *) (intptr_t) n)
然后当你收到“指针”时你做相反的转换:
int n = (int) (intptr_t) ret;
注意需要将i
的值传递给线程,方法相同。不是因为生命周期问题,而是因为所有线程都有完全相同的指针,并且会发生数据争用以获取值,这意味着多个线程似乎可以获得相同的值。
所以当你创建线程时传递值:
pthread_create(&thr, NULL, fonction_thread, (void *) (intptr_t) i)
并在函数中进行相反的转换以获取值:
int n = (int) (intptr_t) arg;