4

我知道如何将一个函数作为另一个函数的参数传递。但我不知道传递给 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

4 回答 4

7

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

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

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

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

编辑

在您的示例中,您还需要通过函数指针调用该函数。就像是:

void (*func)() = argFunc;
funct(); /* <-- */
于 2012-09-12T16:02:45.120 回答
3

严格来说,这是不可能的。根据标准,指向的指针void可能只是转换为指向对象类型的指针或从指向对象类型的指针转​​换。在某些架构上,函数地址大于对象地址。

C11, § 6.3.2.3 指针

指向的指针void可以转换为指向任何对象类型的指针或从指向任何对象类型的指针转​​换。指向任何对象类型的指针都可以转换为指向 void和返回的指针;结果应与原始指针比较。

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

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

指向对象或 tovoid的指针可以转换为指向函数的指针,从而允许将数据作为函数调用 (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;
}
于 2012-09-12T16:41:15.077 回答
3

添加到已经给出的答案:

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

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

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

// ...
struct threadArg *threadArg = malloc(sizeof(threadArg));
threadArg->callback = myFunction;
pthread_create(&idThread, NULL, threadFunction, (void *) threadArg);
于 2012-09-12T16:49:22.843 回答
-1

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

#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);
    .
    .
    .

}
于 2012-09-12T16:50:33.143 回答