首页 > 解决方案 > 将指向 void 的指针作为 pthread_join 的第二个参数传递

问题描述

下面是“高级 Linux 编程”的“线程”部分的示例程序,稍作修改以接收来自命令行参数的输入。

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* The calculation implemented below is not efficient
 * Consult numerical algorithm for better solutions
 */
void *
compute_prime(void *arg)
{
    int candidate = 2;
    int n = *((int *) arg);

    while (1)
    {
        int factor;
        int is_prime = 1;

        for (factor = 2; factor < candidate; ++factor)
            if (candidate % factor == 0)
            {
                is_prime = 0;
                break;
            }
        if (is_prime)
            if (--n == 0)
                return (void *)candidate;
        ++candidate;
    }
    return NULL;
}

int
main(int argc, char **argv)
{
    pthread_t thread;
    int which_prime = atoi(argv[1]);
    int prime;

    pthread_create(&thread, NULL, &compute_prime, &which_prime);
    pthread_join(thread, (void *)&prime);
    printf("The %dth prime number is %d.\n", which_prime, prime);

    return 0;
}

让我困惑的是pthread_join功能。它的原型是

pthread_join(pthread_t, void **)

所以第二个参数是 type void **。同时,在程序void *中传递了一个变量。我认为(void *)&prime确实是一个void *,对。但是如何将 avoid *转换为void **?我检查了源代码,第二个参数的赋值很简单*status = pthread->status

void *自动投射到void **? 我认为这是不允许的,但这个程序使它似乎成为可能。像这样写是不正确的吗?

标签: cpthreads

解决方案


to 的参数pthread_join是一个指针,指向放置您要加入的线程的“退出值”的位置。该退出值(pthread_exit传递给的线程函数的参数或返回的值pthread_create)是 a void *,所以参数pthread_join是 a void **

现在令人困惑的是,在 C 中, avoid *可以在没有强制转换的情况下隐式转换为任何指针类型。因此,将您传递给的值转换为(void *)然后允许它被隐式转换void **并传递。问题是,如果你传递的地址实际上不是 a void *,你会得到未定义的行为。在此示例中,在 64 位机器上, avoid *是 8 个字节,而 aint可能只有 4 个字节,因此这可能会破坏紧接在 . 之后的堆栈帧中的任何内容prime。那可能是which_prime,所以这可能会打印出The 0th prime is... 无论您最初传递的值是什么。0或者它可能会在大端机器上打印素数。


推荐阅读