Problème en multi-threading
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

Problème en multi-threading



  1. #1
    invite19e61be6

    Problème en multi-threading


    ------

    Bonjour à tous,

    je viens de terminer une partie d'une bibliothèque et je souhaiterai la tester au moyen d'un petit programme qui est le suivant :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <semaphore.h>
    #include "lampe.h"
    #include "gpio.h"
    /*******************************************/
    /*		PINS GPIO		   */
    /*******************************************/
    #define PIN_LAMPE 2
    /*******************************************/
    #define PSHARED_BETWEEN_THREADS 0
    #define TEMPS_ACTUAL 30.0
    #define VALEUR_INITIALISATION_SEMAPHORE 1
    #define ADRESSE_FICHIER_LAMPE "/home/nicolas/Documents/lampe.schedule"
    
    int main()
    {
    	struct lampe_args * parametre;
    	parametre=malloc(sizeof(*parametre));
    	parametre->addr=ADRESSE_FICHIER_LAMPE;
    	parametre->TEMPS_ACTUALISATION=TEMPS_ACTUAL;
    	parametre->pin=PIN_LAMPE;	
    	parametre->donnees=NULL;
    	parametre->GPIO_ACCESS=map_memory();
    	
    	pthread_t * thread_lampe;
    	
    	//Initialisation des semaphores
    	sem_init(parametre->sem_GPIO, PSHARED_BETWEEN_THREADS, VALEUR_INITIALISATION_SEMAPHORE);	
    	sem_init(parametre->sem_lampe_file, PSHARED_BETWEEN_THREADS, VALEUR_INITIALISATION_SEMAPHORE);
    
    	//Creation des threads	
    	pthread_create(thread_lampe,NULL,(void * (*)(void *))lampe_main,parametre);
    
    	//Attente des threads
    	pthread_join(*thread_lampe,NULL);
    	
    	//Destruction des semaphores	
    	sem_destroy(parametre->sem_lampe_file);
    	sem_destroy(parametre->sem_GPIO);
    	
    	unmap_memory(parametre->GPIO_ACCESS);
    	free(parametre);
    	return 0;
    }
    Le programme est assez simple conceptuellement.
    La structure paramètre possède toutes les données nécessaires à l’exécution du thread thread_lampe.
    Il y a notamment l'adresse d'un fichier qui sera lu par un thread thread_actualiser_donnees pour actualiser une information de parametre.
    Un autre thread s'execute (le thread_gerer_GPIO) qui va changer la valeur de certains registres en fonction de l'information contenue dans parametre.

    L'utilisation de ressources partagées nécessite l'exécution de deux threads selon moi (peut-être ai-je tort sur ce coup).
    Je n'obtiens aucune erreur à la compilation mais le programme s'arrete automatiquement.
    Je ne comprends pas pourquoi et je pense qu'il s'agit d'une mauvaise manipulation des threads.

    Quelqu'un pour me remettre dans le droit chemin ?

    Merci par avance à tous les lecteurs.

    -----

  2. #2
    Jack
    Modérateur

    Re : Problème en multi-threading

    Code:
        //Creation des threads 
        pthread_create(thread_lampe,NULL,(void * (*)(void *))lampe_main,parametre);
    Je n'en vois qu'un.

    Et où se trouve la fonction lampe_main qui va exécuter le thread?

  3. #3
    invite19e61be6

    Re : Problème en multi-threading

    Merci pour votre réponse rapide.
    Je joins lampe.h et scheduler.h

    lampe.h :
    Code:
    #ifndef LAMPE_H
    #define LAMPE_H
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "scheduler.h"
    
    struct lampe_args
    {
    	struct GPIO_control GPIO_ACCESS;
    	struct data * donnees;
    	unsigned int pin;
    	float TEMPS_ACTUALISATION;
    	char * addr;
    	sem_t * sem_GPIO;
    	sem_t * sem_lampe_file;
    };
    
    void * lampe_main(struct lampe_args * parametre);
    
    #endif
    schedule.h :
    Code:
    #ifndef SCHEDULER_H
    #define SCHEDULER_H
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h> //pour ouvrir les fichiers
    #include <unistd.h>//avec fcntl.h
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <time.h>//pour les structures de temps
    #include <pthread.h>//pour les semaphores
    #include <semaphore.h>//pour les semaphores
    #include "gpio.h"
    
    struct schedule_args
    {
    	struct GPIO_control GPIO_ACCESS;
    	struct data * donnees;
    	unsigned int pin;
    	float TEMPS_ACTUALISATION;
    	char * addr;
    	sem_t * sem_GPIO;
    	sem_t * sem_scheduler_file;
    };
    
    struct data
    {
    	long * ptr_date_event;
    	unsigned char state;	
    };
    
    //Cette fonction lit la première ligne du fichier qui est la date d'initialisation
    static long lire_initializer(FILE * file);
    
    //Cette fonction lit la deuxième ligne du fichier qui est la date butoir
    static long lire_ender(FILE * file);
    
    
    //cette fonction lit la troisième ligne du fichier qui est le temps de la période
    static int lire_period(FILE * file);
    
    static int lire_debut_ligne(FILE * file, int ligne);
    
    static int lire_fin_ligne(FILE * file, int ligne);
    
    //cette fonction renvoie la date du prochaine évenement en variable de type time_t
    static void * actualiser_donnees(struct schedule_args * parametre);
    
    static void * gerer_GPIO(struct schedule_args * parametre);
    
    void * scheduler_main(struct schedule_args * parametre);
    
    #endif
    Dans la fonction scheduler_main, deux threads sont lancés :
    Code:
    void * scheduler_main(struct schedule_args * parametre)
    {
    	pthread_t * thread_actu_data, * thread_gestion_scheduler;
    	pthread_create(thread_actu_data,NULL,(void * (*)(void *))actualiser_donnees,parametre);
    	pthread_create(thread_gestion_scheduler,NULL,(void * (*)(void *))gerer_GPIO,parametre);
    	pthread_join(*thread_actu_data,NULL);
    	pthread_join(*thread_gestion_scheduler,NULL);
    	return NULL;
    }

  4. #4
    Jack
    Modérateur

    Re : Problème en multi-threading

    Avec lamp_main, ça en fait 3.

    De plsu comme on ne sait pas ce que font les threads, comment deviner pourquoi ton programme s'arrête? Si les threads se terminent, ton programme également.

  5. A voir en vidéo sur Futura
  6. #5
    invite19e61be6

    Re : Problème en multi-threading

    Je voulais éviter de publier ces codes parce qu'ils sont vraiment très long mais bon après tout.
    J'ai testé toutes les fonctions que j'utilise notamment actualiser_donnees et gerer_GPIO qui sont en boucle infinie.

    Code:
    static void * actualiser_donnees(struct schedule_args * parametre)
    {
    	FILE * file;
    	int date_debut_event, date_fin_event,period,ligne;
    	long initializer, ender, now;
    	int i;
    	while (1)
    	{
    		now=time(NULL);
    		ligne=0;
    		sem_wait(parametre->sem_scheduler_file);
    		if (file=fopen(parametre->addr,"r"))
    		{
    			initializer=lire_initializer(file);
    			ender=lire_ender(file);
    			period=lire_period(file);
    			if (now <initializer)
    			{
    				*((parametre->donnees)->ptr_date_event)=initializer+lire_debut_ligne(file,0);
    				(parametre->donnees)->state=0;
    			}		
    			else if (now<=ender)		
    			{			
    				do
    				{
    					date_fin_event=initializer+((now-initializer)/period)*period+lire_fin_ligne(file, ligne);
    					ligne++;
    					i=fseek(file,1,SEEK_CUR);
    				}
    				while ((i!=EOF)&&(now>date_fin_event));
    				date_debut_event=initializer+((now-initializer)/period)*period+lire_debut_ligne(file, ligne-1);
    				if (now<date_debut_event)
    				{
    					*((parametre->donnees)->ptr_date_event)=date_debut_event;
    					(parametre->donnees)->state=0;
    				}
    				else if (now > date_fin_event)
    				{
    					*((parametre->donnees)->ptr_date_event)=initializer+((now-initializer)/period+1)*period+lire_debut_ligne(file, 0);
    					(parametre->donnees)->state=0;
    				}
    				else
    				{				
    					*((parametre->donnees)->ptr_date_event)=date_fin_event;
    					(parametre->donnees)->state=1;
    				}	
    			}
    		}
    		fclose(file);
    		sem_post(parametre->sem_scheduler_file);
    		sleep(parametre->TEMPS_ACTUALISATION);
    	}
    	return NULL;
    }
    
    static void * gerer_GPIO(struct schedule_args * parametre)
    {
    	long now=time(NULL);	
    	while (1)
    	{	
    		if (now<*((parametre->donnees)->ptr_date_event))	
    		{	
    			if ((parametre->donnees)->state)
    			{
    				sem_wait(parametre->sem_GPIO);	
    				GPIO_set_output(parametre->GPIO_ACCESS,parametre->pin);	
    				GPIO_set_high(parametre->GPIO_ACCESS,parametre->pin);
    				sem_post(parametre->sem_GPIO);
    			}
    			else
    			{
    				sem_wait(parametre->sem_GPIO);	
    				GPIO_set_output(parametre->GPIO_ACCESS,parametre->pin);	
    				GPIO_set_low(parametre->GPIO_ACCESS,parametre->pin);
    				sem_post(parametre->sem_GPIO);
    			}
    		}
    		else
    		{
    			if ((parametre->donnees)->state)
    			{
    				sem_wait(parametre->sem_GPIO);	
    				GPIO_set_output(parametre->GPIO_ACCESS,parametre->pin);	
    				GPIO_set_low(parametre->GPIO_ACCESS,parametre->pin);
    				sem_post(parametre->sem_GPIO);
    			}
    			else
    			{
    				sem_wait(parametre->sem_GPIO);	
    				GPIO_set_output(parametre->GPIO_ACCESS,parametre->pin);	
    				GPIO_set_high(parametre->GPIO_ACCESS,parametre->pin);
    				sem_post(parametre->sem_GPIO);
    			}
    		}
    	}
    	return NULL;	
    }
    
    J'ai regardé aucun pthread_join ne retourne de valeur alors j'imagine en effet que les threads sont déjà terminés avant que j'exécute pthread_join.

  7. #6
    Jack
    Modérateur

    Re : Problème en multi-threading

    J'ai regardé aucun pthread_join ne retourne de valeur alors j'imagine en effet que les threads sont déjà terminés avant que j'exécute pthread_join.
    Je n'ai pas bien compris ce que tu veux dire. Quel test as-tu effectué?

  8. #7
    invite19e61be6

    Re : Problème en multi-threading

    J'ai juste voulu regarder la valeur que retournait pthread_join dans les trois cas

    Et dans les trois cas, aucune valeur n'est retournée, c'est pourquoi je pense que pthread_join n'est pas exécuté

  9. #8
    invite19e61be6

    Re : Problème en multi-threading

    je crois que mon programme a plusieurs problèmes tout compte fait.

    je reviendrai vers vous avec quelque chose de plus propre à vous montrer (peut-être même la solution).

  10. #9
    polo974

    Re : Problème en multi-threading

    man pthread_create

    VALEUR RENVOYÉE
    En cas de réussite, pthread_create() renvoie 0 ; en cas d'erreur, elle
    renvoie un numéro d'erreur, et le contenu de *thread est indéfini.
    toujours tester les retours des fonctions...
    Jusqu'ici tout va bien...

  11. #10
    Jack
    Modérateur

    Re : Problème en multi-threading

    Et dans les trois cas, aucune valeur n'est retournée
    C'est ce que je ne comprends pas: pthread_join ou pthread_create renvoient forcément une valeur.

  12. #11
    invite19e61be6

    Re : Problème en multi-threading

    Bonjour,
    j'ai résolu mon problème finalement.
    Vous aviez raison il ne s'agissait pas d'une mauvaise manipulation des threads c'était dans le programme actualiser_donnees, une des instructions ne pouvait s'éxecuter parce qu'une variable n'était pas initialisé.

    Je vous remercie pour vos réponses.

    shinishi

Discussions similaires

  1. Threading -
    Par invite0bdb1463 dans le forum Électronique
    Réponses: 15
    Dernier message: 21/03/2015, 23h27
  2. Problème avec multi threading en c sous linux
    Par invite6ae216d1 dans le forum Programmation et langages, Algorithmique
    Réponses: 3
    Dernier message: 11/08/2011, 15h58
  3. [Thermique] Problème climatisation multi spit
    Par invited2da2dc4 dans le forum Dépannage
    Réponses: 2
    Dernier message: 26/05/2011, 16h26
  4. Chargeur (GSM) - multi input - multi output
    Par invite85353d3b dans le forum Électronique
    Réponses: 0
    Dernier message: 15/07/2006, 19h14