pthread_create 第三个参数需要哪种类型

which type does pthread_create need on the third argument

这是 pthread_create 的正确用法,没有任何警告:

#include <pthread.h>
#include <stdio.h>
void  *check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, check , (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

不过下面的代码也可以运行嘛,把void *check改成void check:

#include <pthread.h>
#include <stdio.h>
void check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, check, (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

如果我把check改成&check,也可以运行很好

#include <pthread.h>
#include <stdio.h>
void check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, &check, (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

我看到 pthread_create 的第三个参数是:void *(*start_routine) (void *)
谁能告诉我这是什么意思?

C 标准的任务是编写可移植代码,可以 运行 在任何符合标准的平台上。事实上,运行s 在您的平台上没有明显的错误,并不意味着它在其他平台上也会。失败的原因可能是 pthread_join 可能会尝试访问具有 return 值的硬件寄存器。

它只是一个函数指针。让我们分解一下。 void *(*start_routine) (void *)

void* -> return type of function
start_routine -> function pointer name 
void* -> argument type

您传递的函数的地址将被分配给函数指针 start_routine 并且 start_routine 将作为内核的新线程被调用。

根据 the POSIX standard for pthread_create():

SYNOPSIS

#include <pthread.h>

int pthread_create(pthread_t *restrict thread,
       const pthread_attr_t *restrict attr,
       void *(*start_routine)(void*), void *restrict arg);

这意味着 pthread_create() 的第三个参数必须是 void *(*start_routine)(void*) 形式的函数指针。传递的函数指针必须指向一个函数 声明并定义为

void *start_routine( void *arg )
{
    void *ptr = ...;

    ...
    return( ptr );
}

期间。讨论结束。句号。

您调用 undefined behavior 时没有将 void *(*start_routine) (void *) 类型的函数作为第三个参数传递给 pthread_create()

根据 J.2 Undefined behavior, paragraph 1 of the C standard:

The behavior is undefined in the following circumstances:

...

  • A pointer is used to call a function whose type is not compatible with the referenced type.

"Works with no observed issue" 被 "undefined behavior" 覆盖。 "Program crashes"也涵盖了