IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Interrompre une thread grace au signaux.


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Interrompre une thread grace au signaux.
    Bonjour tout le monde.

    Voila cela fait un petit moment que j'étudie les signaux dans le but de mettre une thread sur pause. Je me heurte à quelque petit souci technique on va dire^^.

    Au bout d'un moment mon programme ce bloque il ce fige tous simplement au lieu de tourner indéfiniment.

    Voila la source. Programme réaliser sous linux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <pthread.h>
    #include <unistd.h>
    #include <signal.h>
     
    using namespace std;
    #define RESUME_SIG SIGUSR2
    #define SUSPEND_SIG SIGUSR1
     
    sigset_t mask, maskold, maskwait,signal_mask;
    volatile sig_atomic_t Continuer = 0;
    int sig;
    struct sigaction sa,su;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    static void *thr_func(void *arg)
    {
    	//Masque tous les signaux à part ce qui suspende et lance la thread
    	sigset_t maskthread;
    	sigfillset(&maskthread);
        	sigdelset(&maskthread, RESUME_SIG);
    	sigdelset(&maskthread, SUSPEND_SIG);
    	pthread_sigmask(SIG_SETMASK, &maskthread, NULL);
    	int *id = (int *)arg;
    	while(1)
    	{
    		usleep(10000);
    		std::cout << "Thread "<< id << std::endl;	
    	}
    	pthread_exit(NULL);
    }
     
    void suspend_thread(int signal)
    {
    	std::cout << "SIGSUSPEND" << std::endl;
        	sigemptyset(&signal_mask);
        	sigaddset(&signal_mask, RESUME_SIG);
        	int sig;
        	sigwait(&signal_mask,&sig);
    	std::cout << "SIGRESUME" << std::endl;
    }
     
    void resume_thread(int signal)
    {
    	cout << "RESUME" << endl;
    	Continuer = 0;
    }
    	//sigemptyset(&sa.sa_mask);
    	//sigaddset(&sa.sa_mask, SUSPEND_SIG);
    int main()
    {
    	pthread_t th;
    	int id = 1, iteration = 0;
    	bool w1 = false;
     
     
    	sigemptyset(&mask);
        	sigaddset(&mask, RESUME_SIG);
    	sigaddset(&mask, SUSPEND_SIG);
    	sigprocmask(SIG_BLOCK,&mask,NULL);
        	pthread_sigmask(SIG_BLOCK, &mask, NULL);
     
    	sigfillset(&sa.sa_mask);
    	sigdelset(&sa.sa_mask, RESUME_SIG);
    	sigdelset(&sa.sa_mask, SUSPEND_SIG);
       	sa.sa_flags = 0;
        	sa.sa_handler = suspend_thread;
        	sigaction(SUSPEND_SIG, &sa, NULL);
     
    	sigfillset(&su.sa_mask);
    	sigdelset(&su.sa_mask, RESUME_SIG);
    	sigdelset(&su.sa_mask, SUSPEND_SIG);
       	su.sa_flags = 0;
        	su.sa_handler = resume_thread;
        	sigaction(RESUME_SIG, &su, NULL);
     
    	pthread_create(&th, NULL, thr_func, (void *)id);
     
    	while(1)
    	{
    		usleep(100000);
    		iteration++;
    		std::cout << "Main " << iteration  << std::endl;
    		if(w1 == false)
    		{
    			std::cout << "Sending Pause"<< std::endl;
    			w1 = true;
    			pthread_kill(th, SUSPEND_SIG);
    			std::cout << "End Sending Pause "<< std::endl;
    		}
    		else
    		{
    			std::cout << "Sending Resume"<< std::endl;
    			w1 = false;
    			pthread_kill(th, RESUME_SIG);
    			std::cout << "End Sending Resume"<< std::endl;
    		}	
    	}
    	return 0;
    }
    En analysant les retours j'ai l'impression que c'est pthread_kill qui bloque à un moment tous simplement. J'ai fais d'autre version pour tester d'autre algo.

    Si quelqu'un à a des idée^^

    Merci d'avance

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    En C++, on utilisera plutôt std::thread (C++11) ou une bibliothèque comme boost::thread ton code, malgré les std::cout ressemble donc plus à du C.

    Sinon, il vaut mieux éviter les signaux qui peuvent interrompre ton thread à n'importe quel moment (et donc générer des erreurs) et préférer l'utilisation d'interruption points à la manière de boost ( http://www.boost.org/doc/libs/1_38_0/doc/html/thread/thread_management.html ) pour arrêter un thread et utiliser des variables de conditions pour les mises en pauses.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup pour ta réponse.

    J'ai cherché un peu des infos sur std::thread avant de répondre^^. Il a l'air moins flexible que pthread, sur certain forum il indique qu'on ne peux pas géré les priorités l'ordonnancement,... Le but de ce système est de mettre la thread sur la pause la ou elle est et qu'elle reprenne sont activé normal une fois le second signaux reçu. Effectivement cela peux poser des problèmes d’accès concurrent.

    Pour le systeme du point d'arrets, je ne peux pas attendre que la thread finisse son travaille avant de repasser par son point d'arrets sinon un simple pthread_cond aurait fait l'affaire^^ à la méthode de boost barriere.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Pour les points d'arrêt, tu peux en placer un peu partout et pour les interruption point de boost, tu en as en plus à l'intérieur de chaque join, sleep, lock de mutex, etc.

    Après, quelle sera le but de ton application et pourquoi as-tu besoin de faire ceci ?

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    effectivement j'aurais peut etre du commencer par la^^. C'est une fonction qui va etre implémenter dans un threadpool pour de l'embarquée.

    Je n'ai donc pas accès à des librairies comme boost et le but en étant le plus prêt possible de la machine et fonctionnent uniquement sur linux.

    Le threadpool est lui meme intégrer a un gestionnaire d'evenement conçu sous le modele du C# et lui fait en c++11^^. Voila pour présenter un peu le truc.

    Je connais pas le code qui va être exécute dans ma thread vue que je suis en threadpool. Si la fonction chargé dans la thread tourne en boucle et que le boss du threadpool souhaite mettre ce thread sur pause et ne connaissant pas le temps avant le prochain point d'arret si il y en a, ben la thread s'arretera jamais.

    Voila pourquoi l'utilisation des signaux. Ce mecanisme me permet a la fois de communiquer des valeurs mais surtout d'etre préemptif sur l'action en cours dans mon thread.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Si tu veux t'amuser, tu pourrais réécrire ton propre ordonnanceur pour tes threads

    Après, il vaut mieux ne pas interrompre certains bout de code trop longtemps ce qui est le cas pour des sections critique par exemple (avec des mutex).

    Est-ce que tu ne peux pas proposer à l'utilisateur des points d'arrêt et avoir à côté un timeout qui permet de mettre en pause le thread s'il n'a pas rencontré de points d'arrêt ? Ainsi on pourra éviter de couper le code n'importe où.

    Après pour pthread, je pense que tu auras plus de réponses dans le forum C.

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Je suis assez d'accord dans l'idée que d'interrompre une thread comme sa ne le fais pas trop surtout avec les sections critique c'est pour cela que je travaille sur la mise en place de moniteur, c'est plus évoluer que le mutex et sous conception objet directement. ceci me permettre de rendre non interruptible un morceaux de code.

  8. #8
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Désolé pour le MP c'etait juste pour ce parler un peu en dehors du forum pour mieux expliquer, ne t'inkiete pas de toute maniere je posterai la réponse que je la trouve ici ou ailleur, il n'y a rien de pire qu'un mec qui poste et qui dit j'ai trouvé sans mettre la réponse^^ sa sens le vécu^^

    Alors le gros du projet c'était d'implémenter un gestionnaire d'évenement en C++ donc j'avais besoin de threadpool de delegate d'event d'un eventdispatcher et tout sa et donc j'en ai deja programmer une partie et la je bloque sur sa et le moniteur. Voila en gros au final le projet j'aimerais l'implémenter dans un kernel pour que meme l'os gere les entrée/sortie en evenement voila en gros^^.

    Pour le moment le but c'est juste de piloté un systeme embarquée avec ce genre de technique^^

    la carte embarquée est une friendlyarm cortex m3 avec un compilateur g++ 4.5.x voila tout^^

    PS excusez moi le double post

Discussions similaires

  1. Thread interrupt, comment interrompre une API tout en libérant les ressources
    Par rpelissi dans le forum Concurrence et multi-thread
    Réponses: 0
    Dernier message: 19/10/2009, 13h30
  2. [Thread] Interrompre un Thread
    Par Arnaud51 dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 13/03/2005, 21h41
  3. [CR] recuperer une durée grace a 2 date
    Par cmgirondins dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 13/01/2005, 07h20
  4. Interrompre une connexion ?
    Par BoBoToTo dans le forum Bases de données
    Réponses: 7
    Dernier message: 29/10/2004, 09h26
  5. Arrêter une Thread brutalement!
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 21h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo