2009-02-25 7 views
4

c compilateur de programmes gccappelant un rappel à partir d'un thread à l'aide de pointeurs de fonction

J'ai 3 fichiers. main.c stop_watch.h et stop_watch.c

Ce programme ne fonctionne pas. J'appelle start_stopwatch. Et il rappellera dans main.c timeout_cb() après que le temps a expiré. Je lance aussi ceci dans un thread séparé, car je ne veux pas bloquer dans le main, car j'aurai d'autres codes à exécuter.

1) Les secondes dans g_start_timer donnent toujours des déchets. Je pensais que j'aurais pu résoudre cela en créant la structure sur le tas. Y at-il de toute façon je peux résoudre ceci. Je pensais créer l'élément seconds sur le tas. Mais pense que c'est fini tuer

2) Ce programme fonctionne bien, mais si je commente la ligne dans printf principal ("=== timeout_cb:% p \ n", timeout_cb); il va pile décharge.

3) quel est le meilleur moment pour libérer de la mémoire. Je le libérais en main. Mais je suis inquiet si la mémoire est libérée avant que le fil ait fini. Cela pourrait provoquer un résultat très inattendu. Je pense que je pourrais utiliser thread_join() comme libre de la mémoire après cet appel. Cependant, je aurais besoin de retourner le thead_id qui est créé dans le stop_watch.c, est-il un moyen de retourner le thread_id qui est créé dans stop_watch.c

Un grand merci pour toutes les suggestions,

principale . 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"); 
} 

Répondre

7

La ligne start_stopwatch():

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

devrait être:

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

Dans le premier cas, vous passez un « pointeur vers un pointeur "quand vous voulez vraiment passer le pointeur comme argument de thread.

En ce qui concerne le moment de libérer les données, il existe de nombreuses options. Si vous toujours transmettre les données de thread dans un bloc alloué tas, alors le proc thread thread g_start_timer() peut le libérer quand il est fini d'extraire les données. Notez que si vous faites cela, une partie du protocole pour démarrer le thread est que le bloc d'argument thread doit être alloué par tas.

Questions connexes