2015-08-18 11 views
5

Linux, C. Ho creato più thread per eseguire carichi di lavoro e desidero segnalare che i thread si fermano/terminano dopo un intervallo di secondi specificato. Come posso implementarlo con C?Linux, C: terminare più thread dopo alcuni secondi (timer?)

void *do_function(void *ptr) 
{ 
    //calculating, dothe workload here; 
} 

int run(struct calculate_node *node) 
{ 
    pthread_t threads[MAX_NUM_THREADS]; 
    for (t = 0; t < node->max_threads; t++) { 
     rc = pthread_create(&threads[t], NULL, do_function, (void*)node); 
     if(rc) return -1; 
    } 

    //how do I create timer here to fire to signal those threads to exit after specified seconds? 


    for (t = 0; t < node->max_threads; t++) { 
     pthread_join(threads[t], NULL); 
    } 
    free(threads); 
} 

grazie!

risposta

4

Non sono sicuro se c'è un modo portatile per creare un evento timer, ma se main non ha nient'altro da fare, potrebbe semplicemente chiamare sleep per perdere tempo.

Per quanto riguarda la segnalazione dei thread, sono disponibili due opzioni: terminazione cooperativa o terminazione non cooperativa. Con la terminazione cooperativa, il thread deve periodicamente controllare un flag per vedere se deve terminare. Con la terminazione non cooperativa, si chiama pthread_cancel per terminare la discussione. (Vedere la pagina man per pthread_cancel per informazioni sulle funzioni aggiuntive che possono essere utilizzate per terminare con garbo il thread.)

Trovo che la terminazione cooperativa sia più facile da implementare. Ecco un esempio:

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

static int QuitFlag = 0; 
static pthread_mutex_t QuitMutex = PTHREAD_MUTEX_INITIALIZER; 

void setQuitFlag(void) 
{ 
    pthread_mutex_lock(&QuitMutex); 
    QuitFlag = 1; 
    pthread_mutex_unlock(&QuitMutex); 
} 

int shouldQuit(void) 
{ 
    int temp; 

    pthread_mutex_lock(&QuitMutex); 
    temp = QuitFlag; 
    pthread_mutex_unlock(&QuitMutex); 

    return temp; 
} 

void *somefunc(void *arg) 
{ 
    while (!shouldQuit()) 
    { 
     fprintf(stderr, "still running...\n"); 
     sleep(2); 
    } 

    fprintf(stderr, "quitting now...\n"); 
    return(NULL); 
} 

int main(void) 
{ 
    pthread_t threadID; 

    if (pthread_create(&threadID, NULL, somefunc, NULL) != 0) 
    { 
     perror("create"); 
     return 1; 
    } 

    sleep(5); 
    setQuitFlag(); 
    pthread_join(threadID, NULL); 
    fprintf(stderr, "end of main\n"); 
} 
2

In primo luogo, è necessario creare e avviare il tempo. Nell'esempio sotto il timer invocherà una funzione di "stop", che sarà responsabile per l'interruzione dei thread. In un certo senso, è una delle opzioni più semplici.

void *notify_stop(void *); // Prototype 

int run(struct calculate_node *node) 
{ 
    ... 

    struct sigevent sev; 
    timer_t timer; 
    struct itimerspec tspec = { 0 }; 
    sev.sigev_notify = SIGEV_THREAD; // type of timer event 
    sev.sigev_notify_function = notify_stop; // call function 
    timer_create(CLOCK_MONOTONIC, &sevent, &timer); 
    tspec.it_interval.tv_sec = 5; // set time interval 
    tspec.it_interval.tv_nsec = 0; 
    tspec.it_value.tv_sec = 0; 
    tspec.it_value.tv_nsec = 0; 
    timer_set(timer, &tspec, NULL); // start timer 

    .... 
} 

Ora, è necessario decidere come si desidera interrompere i thread. Un modo è utilizzare alcune variabili condivise per indicare la condizione di uscita:

volatile bool do_stop = false; 
void *do_function(void *ptr) 
{ 
    while (!do_stop) 
    { 
    //calculating, dothe workload here; 
    } 
} 
void *notify_stop(void *) 
{ 
    do_stop = true; // just set the variable to let other threads 
        // read it and stop 
} 
Problemi correlati