【问题标题】:What is the type of "start_routine" passed to pthread_create传递给 pthread_create 的“start_routine”的类型是什么
【发布时间】:2021-07-24 16:32:49
【问题描述】:

这里是一个在 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 不能只接收一个普通的函数指针

【问题讨论】:

标签: c pthreads


【解决方案1】:

start_routine 的类型是什么?这是指向函数指针的指针吗?

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

void *(*start_routine)(void *)

这是一个指向函数的指针,该函数将void * 指针作为参数 并且具有void *返回 类型

也许这会更清楚:

int (*intfunc_routine)(void *)

这里更明显的是函数/指针的返回类型是int

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

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

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

myThreadFun()

这是对函数的调用

只是在做:

myThreadFun

没有括号)是该函数的地址(即指向函数的指针)。

为什么pthread_create 不能只接收一个普通的函数指针?

正如我们现在所看到的,它确实只接收一个“普通”函数指针


更新:

所以你是说int (*intfunc_routine)(void *) 等于int * (*intfunc_routine)(void *)

不,它们等效。第一个是指向返回int 的函数的指针。第二个是指向函数的指针,该函数将指针返回到int(即int *)。

开头的 int 前面有一个额外的星号。这就是 start_routine 的样子,它的开头有一个额外的星号。 ——丹

语法:

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;
}

【讨论】:

  • 您说通常 pthread 返回码类似于进程退出码,0 表示成功,1 表示错误?也许对于您的代码,但我发现您的约定很不寻常。
  • @pilcrow 可以使用任何想要的约定。但是,SO 充满了使用该特定约定的实例。而且,考虑到 OP 的问题,最好保持简单,而不是引入更复杂/高级的返回值用法。
猜你喜欢
  • 2010-11-24
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多