【问题标题】:how to use pthread for not just void functions with void argument in C/C++?如何在 C/C++ 中将 pthread 用于不只是带有 void 参数的 void 函数?
【发布时间】:2015-05-14 09:40:54
【问题描述】:

我想在main()中调用多个函数并处理它们的返回值(使用pthread_join),但它们都是int函数,具有多个非void参数,pthread_create 的定义为:

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

我在网上找到的start_routine 的所有示例都是void * 类型,类型为单个void * 参数,是否可以在pthread_create 中调用具有多个非空类型参数的int 函数?

【问题讨论】:

  • 您尝试了一些无效的方法吗?
  • 如果我使用int函数,编译时会报错
  • 显示函数decl,并显示exact错误。简而言之,展示您尝试过的任何不起作用的东西,并且请将它放在您的问题中,而不是在 cmets 中。

标签: c types casting pthreads


【解决方案1】:

您想将int 函数包装成所需类型的函数。

因此,假设您想返回 int,您可以这样做:

(该示例假定 C99 并为了便于阅读而省略了相关的错误检查。)

#include <inttypes.h> /* for intptr_t */
#include <stdio.h>
#include <pthread.h>

struct S
{
  int x;
  int y;
};

int sum(int x, int y)
{
  return x + y;
}

void * thread_function(void * pv)
{
  struct S * ps = pv;
  pthread_exit((void *) (intptr_t) sum(ps->x, ps->y));
}


int main(void)
{
  struct S s = {41, 1};
  pthread_t pt;
  pthread_create(&pt, NULL, thread_function, &s);

  void * pv;
  pthread_join(pt, &pv);

  int z = (intptr_t) pv;
  printf("%d + %d = %d\n", s.x, s.y, z);
 }

打印出来:

41 + 1 = 42

intptr_t 之间的转换是必要的,以确保将指针值误用为整数不会违反 C 标准。

【讨论】:

    【解决方案2】:

    如果你查看manual page,你会看到函数参数是

    void *(*start_routine) (void *).
    

    您不能传递不同类型的函数来启动例程。

    您可以使用 (void *) 将参数传递给 start_routine。

    【讨论】:

      【解决方案3】:

      您可以将 pThread 指针转换为与整数兼容的某种类型。更好的解决方案是将整个功能放在包装函数中。请参考以下链接:

      C++, create a pthread for a function with a return type?

      【讨论】:

      • 强制转换函数是个坏主意。这样做会引发不自信的行为。
      • @alk :我同意选角总是一个坏主意。这就是为什么我建议更好的解决方案是将它包装起来。
      【解决方案4】:

      让我们看看我是否理解了这个问题。 你想调用一个带有类似签名的函数

      int myfunct(int a, int b, int c)
      

      然后定义一个这样的结构

      struct my_funct_param_t
      {
          int a ;
          int b ;
          int c ; 
      } ;
      

      以及用作启动例程的包装器

      void *myfunct1(void *arg)
      {
          my_funct_param_t *arg1 = (my_funct_param_t *)arg ;
          myfunct(arg1->a, arg1->b, arg1->c) ;
       ....
      }
      

      启动线程的代码必须创建 my_funct_patam_t 对象并相应地填写。当心这个对象的生命周期......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-23
        • 2014-06-29
        • 2016-07-16
        • 2017-07-13
        • 2014-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多