【问题标题】:How to call a function when its pointer is stored in struct当指针存储在struct中时如何调用函数
【发布时间】:2015-04-10 11:22:51
【问题描述】:

在下面的例子中如何调用函数。

我有一个结构

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;
}

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

我试过了

timing_struct->Timing_Function(1);

然后它就崩溃了。

谢谢

【问题讨论】:

    标签: c pointers struct pthreads


    【解决方案1】:

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

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

    【讨论】:

    • 我在调用函数之前打印了时间->睡眠时间,它的值是我在创建结构时设置的值。你的理论还有可能吗?
    • 在您粘贴整个 MCVE 之前,我的理论仍然是可能的(并且很可能)。事实上,printf(更不用说msleep)造成的延迟可能会让事情变得更糟。
    【解决方案2】:

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

    如果你对pthread_join-ing 线程没问题,这应该做例如:

    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

    【讨论】:

      【解决方案3】:

      我测试了你的代码,它没有崩溃,而是很快就退出了。所以我认为这不是结构中函数指针的问题。要自己确认这一点,请尝试在调用pthread_detach 之前添加pthread_join(delay_thread, NULL);,看看它是否仍然“崩溃”或现在正在按您的初衷工作。

      【讨论】:

      • 您能否添加更多信息,例如这样做的原因!?谢谢。
      猜你喜欢
      • 2020-08-21
      • 2011-08-14
      • 2020-03-30
      • 2016-03-30
      • 2011-02-02
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 2021-06-03
      相关资源
      最近更新 更多