2009-02-25 5 views
4

c program compiler gccвызов обратного вызова из потока с помощью указателей функций

У меня есть 3 файла. main.c stop_watch.h и stop_watch.c

Эта программа действительно работает. Я вызываю start_stopwatch. И это будет обратный вызов в main.c timeout_cb() по истечении времени. Я также запускаю это в отдельном потоке, так как я не хочу блокировать в основном, так как у меня будет другой код, который мне нужно запустить.

1) Секунд в g_start_timer всегда дает мусор. Я думал, что, возможно, решил это, создав структуру в куче. В любом случае я могу это решить. Я думал создать элемент секунд в куче. Но подумайте, что это закончилось.

2) Эта программа работает нормально, но если я прокомментирую строку в основном printf («=== timeout_cb:% p \ n», timeout_cb); он будет складывать дамп.

3) когда самое лучшее время для освобождения памяти. Я освобождал его в основном. Но я беспокоюсь, если память освобождается до завершения потока. Это может вызвать очень неожиданный результат. Я думаю, что я мог бы использовать thread_join(), чтобы освободить память после этого вызова. Тем не менее, я должен был бы вернуть thead_id, который создается в stop_watch.c, есть способ вернуть thread_id, созданный в stop_watch.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"); 
} 

ответ

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() может освободить его, когда он закончит вытягивать данные. Обратите внимание: если вы это сделаете, то часть протокола для запуска потока состоит в том, что блок аргументов потока должен быть выделен кучей.