首页 > 解决方案 > 如何获得由 pthread 运行的函数的返回值?

问题描述

我的 C 程序有问题,我想我需要一些帮助。我的程序正在使用多个线程进行一些计算。每个线程运行一个只有一个参数的方法,最后返回一个整数。

现在,为了完成我的计算,有必要取所有子计算的总和,即线程返回的所有整数的总和。

但不知何故,这个结果是不正确的。我认为我在从线程中获取所有返回的整数时犯了一个错误。这是我的代码:

//creating the threads (with splitArray[] as an array of pointers to other arrays)
pthread_t threads[n];
for (int i = 0; i < n; i++) {
  pthread_create(&threads[i], NULL, (void * )(countPrime), (void * )splitArray[i]);
}


//getting the results of the threads
int numPrimes = 0;
int save;
for (int i = 0; i < n; i++) {
    pthread_join(threads[i],(void **) &save);
    numPrimes = numPrimes +  save;
}

这是每个线程的方法:

 int countPrime(int array[]) {
    int numPrimes = 0;

    for (int i = 0; i < size; i++) {
        //checking if array[i] is a prime number
        if (isPrime(array[i])) {
            numPrimes++;
        }
    }
    return numPrimes;
 }

我犯错了吗?我是 C 的新手,所以我对使用指针并不是很有信心,这在这种情况下似乎是必要的。

非常感谢 :)

标签: cmultithreadingjoinreturnpthreads

解决方案


线程函数应该返回一个void *指针,在 64 位机器void *上通常是 64 位宽,而int通常只有 32 位宽。

当你从一个预期返回 64 位值的函数返回一个 32 位值时,额外的 32 位值有什么用?这是未知的,因此您的代码表现出未定义的行为

要解决您的问题(我认为可能是这样),您需要更新线程函数以返回正确的类型(void *)并进行一些转换以确保您返回的值具有正确的类型和大小:

void *countPrime(int array[]) {
    ...
    return (void *) (intptr_t) numPrimes;
}

然后,当您获取值时,您还需要使用正确的类型,并使用相反的转换:

void *result;
for (int i = 0; i < n; i++) {
    pthread_join(threads[i],&result);
    numPrimes = numPrimes +  (int) (intptr_t) result;
}

请注意,返回这样的非指针值(以及将非指针值作为参数传递给线程函数)几乎是大多数人同意这种强制转换是可以的唯一情况。否则,它通常永远不会。


推荐阅读