2009-02-25 53 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()線程處理程序可以在完成將數據拉出時釋放它。請注意,如果你這樣做,那麼啓動線程的協議的一部分就是線程參數塊必須被分配堆。