pthread函数的参数可以是另一个函数吗?

时间:2012-09-12 16:01:36

标签: c pthreads

我知道如何将函数作为另一个函数的参数传递。但我不知道传递给pthread的函数的参数是否可以是另一个函数。这甚至可能吗?

以下是编译好的示例代码,但不起作用:

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

pthread_t idThread;

void aFunction(){
    while(1){
        fprintf(stderr,"I've been called!\n");
        usleep(1000000);
    }
}

void * threadFunction(void *argFunc){
    // Do here some stuff;
    // ...

    // Now call the function passed as argument
    void (*func)() = argFunc;
}    

int thread_creator(void(*f)()){
    // I want to use as argument for threadFunction the f function
    pthread_create(&idThread, NULL, threadFUnction, (void *)f);
}

int main(){
    thread_creator(aFunction);
    while(1);
    return 0;
}

4 个答案:

答案 0 :(得分:7)

如果你愿意稍微弯曲规则,它可以是一个函数指针。严格来说,void *不能保证能够保存函数指针。像这样(未经测试):

void some_fun()
{
    /* ... */
}

void thread_fun(void *arg)
{
    void (*fun)() = arg;
}

pthread_create(...., (void *) some_fun);

修改

在您的示例中,您还需要通过函数指针调用该函数。类似的东西:

void (*func)() = argFunc;
funct(); /* <-- */

答案 1 :(得分:3)

严格地说,这是不可能的。根据标准,指向void的指针可以仅转换为指向对象类型的指针。在某些体系结构中,函数地址大于对象地址。

  

C11,§6.3.2.3指针

     

指向void的指针可以转换为指向任何对象的指针   类型。指向任何对象类型的指针可以转换为指向   void再回来;结果应与原始数据相等   指针。

否则,这是一个常见的扩展名。

  

C11,§J.5.7函数指针强制转换

     

指向对象或void的指针可以转换为指向a的指针   函数,允许将数据作为函数调用(6.5.4)。

在您的示例中,您不要拨打func

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

pthread_t idThread;

void aFunction(void)
{
    while (1) {
        fprintf(stderr, "I've been called!\n");
        usleep(1000000);
    }
}

void *threadFunction(void *argFunc)
{
    void (*func)(void) = argFunc;
    func(); /* HERE */
}

int thread_creator(void (*f)(void))
{
    pthread_create(&idThread, NULL, threadFUnction, (void *) f);
}

int main(void)
{
    thread_creator(aFunction);
    while (1);
    return 0;
}

答案 2 :(得分:3)

添加已经给出的答案:

从概念上讲,函数指针可以像任何其他类型的指针一样传递,但是 - 正如已经指出的那样 - void *不能保证足够大以容纳函数指针,只有数据指针

pthread_create回调函数之类的解决方法是将所需的函数指针包装在用作用户数据的结构中:

struct threadArg
{
    void (*callback)(void);
};

// ...
struct threadArg *threadArg = malloc(sizeof(threadArg));
threadArg->callback = myFunction;
pthread_create(&idThread, NULL, threadFunction, (void *) threadArg);

答案 3 :(得分:0)

不需要涉及函数指针的可疑强制转换。线程的参数可以是指向可以包含任何内容的结构的指针。

#include <pthread.h>

struct arg {
    void (*func)(void);
    int other_stuff;
};

void function(void)
{

}

void *thread_function(void *arg)
{
    struct arg *a1 = arg;

    a1->func();

    return NULL;
}


int main(void)
{
    pthread_t tid;

    struct arg arg = {.func = function};

    pthread_create(&tid, NULL, thread_function, &arg);
    .
    .
    .

}