pthreads_create(...)执行的函数-指针混乱

时间:2018-07-11 08:33:42

标签: c multithreading pointers pthreads function-pointers

因此,我正在通过POSIX pthreads进入C语言中的多线程,但是我确实在指针的一般概念及其引用和解引用机制方面感到困惑。 中的参数之一 pthread_create(...,pthread_attr_t *attr,...) 是一个函数指针。

此函数通常这样声明:

void *thr_func(void *arg){ thread_data_t *data = (thread_data_t *)arg; ... }

thr_func是一个函数指针,因此通常我会使用&来引用一个函数指针,例如:

thr_func = &thr_func_impl;

thr_func的参数也是通过*取消引用的指针,以检索它们指向的值。

我不理解的是以下内容:

  • 创建线程时,为什么只在pthread_create(...,thr_func,...)中给出函数名称而不是地址,以便可以使用它,例如:pthread_create(...,&thr_func,...)或由{ {1}}已经?

  • 我如何理解这一部分: pthread_create()好吧,我想取消引用 类型thread_data的结构通过thread_data_t *data = (thread_data_t *)arg;称为data。 我不应该这样吗? thread_data_t *data = ...

->我真的不能跟踪其中发生的事情:

thread_data_t *data; data = &arg; /* now * on data ,e.g.: *data == struct-data (dereferencing) gives the struct data and data without * just gives the structs start address */

如果有人能很好地解释我会很高兴,谢谢!

2 个答案:

答案 0 :(得分:1)

  1. 将函数名称作为参数传递等同于使用&运算符传递其地址。即pthread_create(...,thr_func,...)pthread_create(...,&thr_func,...)是可互换的。这与pthreads无关,它是一种语言构造。
  2. arg是类型void的指针。为了将其强制转换为类型thread_data_t的指针,您应该执行(thread_data_t *)arg。通过使用thread_data_t *data = &arg,您会将arg本身的地址归因于data,而不是地址arg指向的地址。

请考虑以下内容:

int my_int = 7;
void *my_void_ptr = &my_int;

int *my_int_ptr = (int *)my_void_ptr; // Just a cast, points to my_int
printf("%d", *my_int_ptr);            // 7
int *my_int_ptr2 = &my_void_ptr;      // int pointer to the address of my_void_ptr, issues a warning
printf("%d", *my_int_ptr2 );          // The address of my_void_ptr as an integer

最后,pthreads代表POSIX线程,因此“ POSIX pthreads”是多余的。

答案 1 :(得分:0)

对于第一个问题,函数自然会衰减为指向自身的指针,类似于数组衰减为指向其第一个元素的指针的方式。

所以,如果您有功能

void *thr_fun(void *arg) { ... }

然后,您可以使用&thr_fun传递指向它的指针,这是显式且(有些人会说)“正确”的方式。另一种方法是使用普通thr_fun,因为它无论如何都会衰减到&thr_fun。因此,在C语言中,这实际上是关于样式和个人喜好的问题。


对于第二个问题,请记住void *是一个通用指针,可以指向任何内容,但没有任何显式类型。因此,您不能取消引用它(因为被取消引用的void *的类型为void)。

这就是您需要投射它的原因。

不,您不应该不要获取指针的地址,因为这将为您提供指向指针的指针