使用函数指针从线程中调用回调函数

5

c语言编译器gcc

我有三个文件。main.c、stop_watch.h和stop_watch.c

这个程序可以工作。我调用start_stopwatch。在时间到期后,它会在main.c中回调timeout_cb()。我还在一个单独的线程中运行它,因为我不想在主线程中阻塞,因为我还需要运行其他代码。

1)g_start_timer中的秒总是给出垃圾值。我认为通过在堆上创建结构体来解决这个问题。有没有办法可以解决这个问题。我正在考虑在堆上创建秒元素。但我认为这太过了。

2)这个程序很好用,但如果我在main中注释掉printf("=== timeout_cb: %p\n", timeout_cb);这一行,它就会堆栈溢出。

3)什么时候释放内存最好。我在main中释放它。但我担心如果在线程完成之前释放内存。那可能会导致非常意外的结果。我在想我可以使用thread_join(),然后在此调用之后释放内存。但是,我需要返回在stop_watch.c中创建的线程ID,有没有办法返回在stop_watch.c中创建的线程ID?

非常感谢任何建议,

main.c

/* main.c */
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>

#include "stop_watch.h"

/* call this when the time expires */
void timeout_cb()
{
    printf("=== your time is up run some job here ===\n");
}

int main()
{
    struct data_struct *g_data_struct =
        (struct data_struct*) calloc(1, sizeof(*g_data_struct));

    if(!g_data_struct)
    {
        printf("=== failed to allocate memory ===\n");
        return 0;
    }

    g_data_struct->seconds = 3;
    g_data_struct->func_ptr = timeout_cb;

    //  printf("=== timeout_cb: %p\n", timeout_cb);

    start_stopwatch(g_data_struct);

    // free(g_data_struct);
    printf("=== End of Program - all threads in ===\n");

    pthread_exit(NULL);

    return 0;
}

stop_watch.h

/* stop_watch.h */
struct data_struct
{
    int seconds;
    void (*func_ptr)(void);
};
void start_stopwatch(struct data_struct *g_data_struct);

stop_watch.c

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

#include "stop_watch.h"

static void* g_start_timer(void *args)
{
    void (*function_pointer)();

    int seconds = ((struct data_struct*) args)->seconds;
    function_pointer = ((struct data_struct*) args)->func_ptr;

    printf("=== go to sleep for %d\n", seconds);

    sleep(seconds);

    (void) (*function_pointer)();

    pthread_exit(NULL);

    return 0;
}

void start_stopwatch(struct data_struct *g_data_struct)
{
    pthread_t thread_id;
    int rc;

    int seconds = g_data_struct->seconds;
    printf("=== start_stopwatch(): %d\n", seconds);

    rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);

    if(rc)
        printf("=== Failed to create thread\n");
}
1个回答

8

start_stopwatch()函数中的代码行:

rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) &g_data_struct);

should be:

rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) g_data_struct);

在第一种情况下,你传递的是“指向指针”的参数,而实际上你只需要将指针作为线程参数传递即可。
至于何时释放数据,有很多选择。如果你总是在堆中分配块来传递线程数据,那么g_start_timer()线程过程可以在完成数据提取后释放它。请注意,如果这样做,启动线程的协议的一部分就是线程参数块必须在堆中分配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接