【问题标题】:Pass function pointer in parameter to pthread_create, (C)将参数中的函数指针传递给 pthread_create,(C)
【发布时间】:2012-07-11 02:12:47
【问题描述】:

这是一个说明我的问题的最小示例

test.c:

#include <stdio.h>
#include <pthread.h>

#define CORES 8

pthread_t threads [ CORES ];
int threadRet [ CORES ];

void foo ()
{
   printf ("BlahBlahBlah\n" );
}

void distribute ( void ( *f )() )
{
   int i;

   for ( i = 0; i < CORES; i++ )
   {
      threadRet [ i ] = pthread_create ( &threads [ i ], NULL, f, NULL );
   }
   for ( i = 0; i < CORES; i++ )
   {
      pthread_join ( threads [ i ], NULL );
   }
}

int main ()
{
   distribute ( &foo );
   return 0;
}

Vim/gcc 输出:

test.c:20|11| warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
/usr/include/pthread.h:225|12| note: expected ‘void * (*)(void *)’ but argument is of type ‘void (*)()’

我需要添加/删除什么&amp; 才能将foo 传递给distribute,然后将其传递给线程?

【问题讨论】:

    标签: c multithreading gcc pthreads


    【解决方案1】:
    void *foo (void *x)
    {
       printf ("BlahBlahBlah\n" );
    }
    
    void distribute ( void * (*f)(void *) ) {
      /* code */
    }
    

    应该做的伎俩

    因为原型是:

    extern int pthread_create (pthread_t *__restrict __newthread,
                               __const pthread_attr_t *__restrict __attr,
                               void *(*__start_routine) (void *),
                               void *__restrict __arg) __THROW __nonnull ((1, 3));
    

    【讨论】:

      【解决方案2】:

      建议的最低更改是:

      void *foo(void *unused)
      {
          printf("BlahBlahBlah\n");
          return 0;
      }
      
      void distribute(void *(*f)(void *))
      {
          ...as before...
      }
      

      pthread_create() 函数需要一个指向函数的指针,该函数接受 void * 参数并返回 void * 结果(尽管您还没有遇到该错误)。因此,通过将foo() 转换为接受void * 参数并返回void * 结果的函数,将指针传递给该类型的函数。而且,对于它的价值,您几乎可以肯定地将 foo() 变成一个静态函数,因为您不太可能直接从该文件外部调用它。

      【讨论】:

      • @DavidSchwartz 我不关注
      • @puk:线程启动例程必须将void * 作为参数,并且还必须返回void *。你不能绕过这个要求。要调用pthread_create,这是您需要拥有的函数类型,因为这是它可以调用的唯一函数类型。
      • @DavidSchwartz:是的-在您发表评论时修复了该问题(尽管在发布答案的原始版本后我记得返回类型)。谢谢。
      • @JonathanLeffler Classic SO "先发帖,稍后编辑"
      • @puk:是的 - 与关于返回类型的错误记忆有关,因为我被您试图提供要调用的函数所误导。我想它很快就修好了。从评论时间戳来看,在 3 分钟内。
      【解决方案3】:

      这个页面似乎解释得很好:http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Fapis%2Fusers_14.htm;

      IBM 文档通常非常好,当它们出现时请留意那些 ibm 链接;)。

      因此,显然您需要一个函数指针,其参数中包含一个 void 指针。试试

      void distribute ( void *( *f )(void *) ) {...}
      

      不过,您可能还需要更改对 foo 的定义。有关函数指针,请参阅以下教程:http://www.cprogramming.com/tutorial/function-pointers.html。注意:我自己没有测试过,所以不能保证它是否会起作用——但我希望它至少可以为你指明正确的方向;)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-31
        • 2016-11-07
        • 2021-05-22
        • 2019-03-12
        • 1970-01-01
        相关资源
        最近更新 更多