2009-02-25 115 views
4

c程序编译器gcc使用函数指针从线程调用回调

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

该程序可以工作。我打电话给start_stopwatch。它将在时间到期后在main.c timeout_cb()中回调。我也在一个单独的线程中运行它,因为我不想在main中阻塞,因为我需要运行其他代码。

1)g_start_timer中的秒数总是给出垃圾。我想我可能通过在堆上创建结构来解决这个问题。无论如何,我可以解决这个问题。我正在考虑在堆上创建秒元素。但认为这是过度杀死

2)这个程序工作正常,但如果我注释掉主printf(“=== timeout_cb:%p \ n”,timeout_cb)行;它会堆积转储。

3)何时是释放内存的最佳时间。我主要解放了它。但是我担心在线程完成之前内存是否被释放。这可能会导致一个非常意外的结果。我想在这个调用之后我可以使用thread_join()来释放内存。不过,我需要返回在stop_watch.c创建的thead_id,是有办法返回在stop_watch.c创建

的任何建议非常感谢,

主力的thread_id。 ç

/* 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"); 
} 

回答

7

start_stopwatch()行:

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

应该是:

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

在第一种情况下,你传递一个“指针的指针“当你真的只想传递指针作为线程参数。

至于什么时候释放数据,有很多选项。如果你愿意总是将线程数据传递给堆分配的块,那么g_start_timer()线程处理程序可以在完成将数据拉出时释放它。请注意,如果你这样做,那么启动线程的协议的一部分就是线程参数块必须被分配堆。