2010-07-20 6 views
3

Comment puis-je implémenter l'interruption minuterie à l'aide de pthreads?Interruption de minuterie pour pthreads

+0

Voulez-vous dire une interruption de minuterie NMI axée sur le matériel (ce que je ne pense pas que l'on puisse faire au niveau du thread) ou simplement lancer une activité à intervalles réguliers? –

+0

Si c'est ce que vous voulez dire, vous ne pouvez pas interrompre un thread pour lui faire exécuter du code, puis lui dire de revenir à ce qu'il faisait auparavant; C'est ce qu'on appelle la commutation de contexte et est fait par les systèmes d'exploitation – Tomaka17

+0

Cependant, vous pouvez vérifier une condition à intervalles réguliers et faire quelque chose quand c'est vrai, mais vous n'avez besoin de rien de spécial pour cela – Tomaka17

Répondre

3

Je n'ai jamais vu une telle installation dans pthread lui-même, mais vous pouvez toujours utiliser un gestionnaire SIGALARM qui notifierait un thread en utilisant un semaphore.

EDIT:

#include <iostream> 
#include <string.h> 
#include <errno.h> 

#include <unistd.h> 
#include <signal.h> 

#include <pthread.h> 
#include <semaphore.h> 

static sem_t __semAlaram; 

static void* waitForAlaram(void*) 
{ 
    while(true) 
    { 
     sem_wait(&__semAlaram); 
     std::cout << "Got alaram" << std::endl; 
    } 
    return NULL; 
} 


typedef void (*sighandler_t)(int); 
static sighandler_t __handler = NULL; 
static int count = 0; 

static void sighandler(int signal) 
{ 
    if (signal == SIGALRM) 
    { 
     count++; 
     sem_post(&__semAlaram); 
     alarm(3); 
    } 
    else if (__handler) 
     __handler(signal); 
} 

int main(int argc, char **argv) 
{ 
    if (sem_init(&__semAlaram, 0, 0) != 0) 
    { 
     std::cerr << strerror(errno) << std::endl; 
     return -1; 
    } 

    pthread_t thread; 
    if (pthread_create(&thread, NULL, waitForAlaram, NULL) != 0) 
    { 
     std::cerr << strerror(errno) << std::endl; 
     return -1; 
    } 

    __handler = signal(SIGALRM, sighandler); 
    alarm(3); 

    while(count < 5) 
    { 
     sleep(1); 
    } 
    return 0; 
} 

Une autre façon de le faire serait d'utiliser simplement le sommeil/usleep dans le fil lui-même.

2

Que diriez-vous de créer un thread, et dans la fonction thread appelant sleep() dans une boucle avec votre intervalle de temporisation souhaité comme valeur de sommeil, appelant à chaque fois votre fonction de rappel timer "interruption"?

0

usleep rendra l'over-end de tous les temps. à la fin de l'année, vous auriez dérivé un peu, c'est pourquoi linux fournit des minuteurs.