如何在指针存储在struct中时调用函数

时间:2015-04-10 11:22:51

标签: c pointers struct pthreads

如何在以下示例中调用该函数。

我有一个结构

struct Timing_Thread_Struct {
    int SleepTime;
    void (*Timing_Function)(int);
};

我有功能,我填充结构并创建一个线程

struct Timing_Thread_Struct timing_struct;
timing_struct.SleepTime = 30;
timing_struct.Timing_Function = ExampleFunction;
pthread_create(&delay_thread, NULL, Delay_Thread_Function, (void *)&timing_struct);
pthread_detach( delay_thread);

示例函数是

void ExampleFunction(int event) {
    //Turn on a digital channel
}

最后我的Delay_Thread_Function

void *Delay_Thread_Function(void *arguments)
{
    struct Timing_Thread_Struct *timing_struct = arguments;
    msleep(timing_struct -> SleepTime );

    //How do i call the function here?

    pthread_exit(NULL);
    return NULL;
}

如何调用存储在struct中的函数?

我试过了

timing_struct->Timing_Function(1);

它只是崩溃了。

由于

3 个答案:

答案 0 :(得分:1)

线程a创建struct Timing_Thread_Struct timing_struct;并触发线程b,然后返回,在此过程中销毁timing_struct。线程b尝试访问被销毁的timing_struct,并因此获得垃圾。假设timing_struct的持续时间比在其下创建的线程更长,这是一个常见的错误。

这可能通过使用pthread_join暂停执行调用线程来解决。

答案 1 :(得分:0)

我测试你的代码并没有崩溃,相反它只是很快就退出了。所以我认为这不是结构中函数指针的问题。要自行确认,请在致电pthread_join(delay_thread, NULL);之前添加pthread_detach,然后查看它是否仍然“崩溃”或现在是您的初衷。

答案 2 :(得分:0)

正如在其他答案中提到的那样,你依赖于timing_struct变量的存在,但这可能不是真的。

如果您对pthread_join没问题,那么应该这样做:

pthread_join(delay_thread, NULL); // instead of detach

请参阅live example

否则(如果你必须分离)你应该以某种方式保证结构的存在,例如你可以制作一个本地副本并使用mutex保护该过程并使用conditional变量发回信号

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

bool created = false; // it's global just to make the example minimal 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct Timing_Thread_Struct {
    int SleepTime;
    void (*Timing_Function)(int);
};    

void ExampleFunction(int event) { printf("Hi it's %d\n", event);}        

void *Delay_Thread_Function(void *arguments)
{
    pthread_mutex_lock(&mutex);
    struct Timing_Thread_Struct timing_struct = *((struct Timing_Thread_Struct*)arguments);
    created = true;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    // now this thread has it's own copy of the struct so the calling thread can end safely
    timing_struct.Timing_Function(timing_struct.SleepTime);

    pthread_exit(NULL);
    return NULL;
}

int main(void){
    struct Timing_Thread_Struct timing_struct;
    pthread_t delay_thread;    
    timing_struct.SleepTime = 30;
    timing_struct.Timing_Function = ExampleFunction;
    pthread_create(&delay_thread, NULL, Delay_Thread_Function, (void *)&timing_struct);
    pthread_detach(delay_thread);


    pthread_mutex_lock(&mutex);
    while(!created){
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
    return 0;
}

Live example