传递给 pthread_create 的 "start_routine" 的类型是什么

What is the type of "start_routine" passed to pthread_create

下面是在 C:

中创建新线程的例子
void *myThreadFun(void *vargp){
   //
}
   
int main(){
    pthread_t thread_id;
    pthread_create(&thread_id, NULL, myThreadFun, NULL);
    pthread_join(thread_id, NULL);
    exit(0);
}

linux man pages 我可以看到 pthread_create 定义如下:

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

这是我的问题:

  1. start_routine的类型是什么?这是一个指向函数指针的指针吗?

  2. *myThreadFun的类型是什么?和上面一样吗?指向函数指针的指针?

  3. 为什么 pthread_create 不能只接受一个普通的 函数指针

what is the type of start_routine? is this a pointer to a function pointer?

不,这只是一个指向函数的[简单]指针:

void *(*start_routine)(void *)

这是一个指向函数的指针,该函数采用 void * 指针作为 参数 并且具有 return 类型 void *

也许这会更清楚:

int (*intfunc_routine)(void *)

这里更明显的是function/pointer的return类型是一个int

虽然来自线程函数的return是一个void *,但这更像是一个“return代码”。通常的 return 是 return (void *) 0; 表示成功,(例如)return (void *) 1; 表示错误。这类似于 main

的 return 值

What is the type of *myThreadFun? same as above? a pointer to a function pointer?

再一次,myThreadFun 只是前面提到的类型的函数。当一个人这样做时:

myThreadFun()

这是对函数的调用

正在做:

myThreadFun

(without the parenthesis) 是那个函数的address(即指向函数的指针)。

Why can't pthread_create just take in a normal function pointer?

正如我们现在所见,它确实只是接受了一个“普通”函数指针


更新:

So you are saying int (*intfunc_routine)(void *) is equal to int * (*intfunc_routine)(void *) ?

不,它们等同。第一个是指向 returns int 的函数的指针。第二个是指向函数的指针,该函数 return 是 指针 指向 int(即 int *)。

There is extra asterisk in front of int in the beginning. That's what start_routine looks like, it has an extra asterisk in the beginning. – Dan

语法:

return_value_type (*func_pointer)(anyargs);

(*func_pointer) 指定了一个指向函数的指针。 return_value_type 可以是任何有效类型(例如 voidintchar *double 等)。 anyargsfunc_pointer.

指向的函数的参数列表

考虑(例如)malloc 的前向声明。这将在 stdlib.h 中,您也可以在 man malloc:

中看到它
void *malloc(size_t size);

将其转换为函数指针(例如):

void *(*pointer_to_malloc)(size_t size);

这是一个小程序:

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

// pointer to function that is compatible with malloc
void *(*pointer_to_malloc)(size_t size);

void *
safe_malloc(size_t size)
{
    void *ptr;

    ptr = malloc(size);
    if (ptr == NULL) {
        fprintf(stderr,"safe_malloc: malloc failure size=%zu -- %s\n",
            size,strerror(errno));
        exit(1);
    }

    return ptr;
}

int
main(void)
{

    // we can do this ...
    pointer_to_malloc = malloc;

    // but we like this function better
    pointer_to_malloc = safe_malloc;

    // now anyone can do this ...
    int *arr = pointer_to_malloc(128);

    printf("main: arr=%p\n",arr);

    free(arr);

    return 0;
}