【问题标题】:Why do we pass function arguments as void* in pthread_create?为什么我们在 pthread_create 中将函数参数作为 void* 传递?
【发布时间】:2016-05-04 14:09:03
【问题描述】:

我刚刚开始了操作系统课程,目前我们正在学习多线程,所以我对这一切都很陌生。

这是我的问题:每当我们使用 pthread_create() 创建线程时,为什么我们需要传递我们希望线程以 void* 类型运行的函数的参数?

例如,考虑以下代码。

void *test(void* data)
{
   ...
}

int main()
{
      int temp;
      pthread_t tid;
      pthread_attr_t attr;
   
      pthread_attr_init(&attr);
      pthread_create(&tid, &attr, test, (void*)&temp);
}

所以,在这里,

pthread_create(&tid, &attr, test, (void*)&temp);

为什么我们需要将整数类型强制转换为 void*。为什么不按原样传递整数?同样,而不是

void* test(void* data);

为什么不这样,

void* test(int data);

【问题讨论】:

  • 想想如何声明pthread_create。您将如何以在 C 中也适用的方式为所有类型声明它?
  • 如果你想传入两个ints,或者任何其他组合怎么办?
  • pthreads 是一个 C api。没有重载,没有模板等。必须有一个固定的接口,可以允许调用各种函数。当你使用 C++ 线程时,你 really do pass the arguments as their real types.

标签: c++ multithreading operating-system


【解决方案1】:

首先,pthread_create() 是一个 C 函数,而不是 C++,所以此时 C++可以 做的所有事情——例如使用模板的东西 - 是不可能的。 C 程序也想启动线程。

(实际上更新版本的 C++ 有自己的threading interface。)

所以,C.

这个想法是有一个 generic 接口,所以你可以将 anything 传递给 any 函数以被pthread_create() 调用,并且返回任何东西。

你不能传值,因为你不知道参数的大小。是intdouble 还是struct something?所以需要通过指针来传递。

而且由于您也不知道参数(和返回值)的类型,因此您使用void *,即“匿名”指针类型。在被调用的线程函数(本例中为test())内部,您确实知道参数的类型和返回值,因此您可以根据需要从void * 进行转换。

【讨论】:

  • 谢谢...我无法弄清楚这么基本的概念,我是多么愚蠢...谢谢顺便说一句:)
  • @MuzahirHussain:真的是 C 的基本概念。每当你看到void *,它的意思是“通用的something”。参考。 memcpy()qsort()bsearch()。一旦您意识到这一点,void * 将永远不会再让您感到困惑。只是,不要在 C++ 中使用void *,它基本上总是是一个设计缺陷。
  • 这听起来很合理。但是,printf() 表明,在 C 语言中,您实际上可以将可变数量的参数传递给函数,而无需限制大小、类型或数量。那么,为什么不 pthread_create(pthread_t*, pthrad_attr_t*, ...) 呢?我相信真正的原因是 POSIX 是故意简单的。
  • @MSalters:可变参数正在解决一个不同的问题,即可变长度参数列表的问题。我们知道这里参数的确切数量,我们只是不知道它们的确切类型。此外,您仍然需要将它们从堆栈中拉出void *,因为没有什么可以告诉您type实际上“隐藏”在它后面(没有@987654339 @-style 格式字符串)。您将一无所获,并添加了可能的错误原因(参数类型太少/错误)
  • @DevSolar:为什么我需要以void* 的身份从堆栈中拉出它们? pthread_create 无论如何都需要为我创建一个堆栈。它可以将整个可变参数列表复制到新堆栈,因此我的线程入口函数可以使用普通可变参数机制检索它们。请记住,在pthread_create 中,调用者控制双方。我知道我通过了什么。
猜你喜欢
  • 2021-11-19
  • 2012-11-19
  • 1970-01-01
  • 2021-11-20
  • 2014-03-12
  • 2018-01-08
  • 1970-01-01
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多