只有从线程返回的第一个值是错误的 (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;