Problème avec variables globales et threads
Bonjour,
Je m'adresse à vous dans l'espoir de trouver une réponse à mon problème (bien entendu j'ai déjà fait le tour de google et de la FAQ).
J'ai un programme constitué de :
struct.h -> contient toutes les includes et les definitions des variables globales
Code:
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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
#ifndef _STRUCT_H_
#define _STRUCT_H_
/* inclusion des bibliotheques necessaires */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//#include <stdbool.h>
#include <pthread.h>
#include <ncurses.h>
/* Definition des constantes du programme */
#define TAILLE_TABLE 1009
#define TAILLE_DESTINATION 20
#define TAILLE_NOM 20
#define TAILLE_PRENOM 20
#define TAILLE_COMPAGNIE 30
#define TAILLE_NUMERO 2
#define TAILLE_MAIL 50
#define TAILLE_MODELE 10
#define TAILLE_DATE 8
#define TAILLE_DESCRIPTION 1000
#define TAILLE_NUMERO_VOL 5
/* Definition du temps minimum avant un echange */
// 10 jours en secondes
#define TEMPS_ANNUL 864000
// Constante pour les arbres AVL
#define EQUILIBRE 0
#define VERS_GAUCHE +1
#define VERS_DROITE -1
// Constante pour la table de hash
#define NON_TROUVE -1
// Pour l'identification
#define NON_IDENTIFIE -1
// Pour l'affichage
#define LARGEUR 100
#define HAUTEUR 50
/* Petite macro bien pratique */
#define ABS(a) ((a) > 0 ? (a) : (-(a)))
/****************************************************************************
DECLARATION DES STRUCTURES UTILISEES DANS LE PROGRAMME
****************************************************************************/
/* Structure pour les clients avec les structures pour la gestion de la
fidelite du client et celle de l'historique de ses vols */
struct histo{
long date;
char destination[TAILLE_DESTINATION];
char num_vol[TAILLE_NUMERO_VOL];
long km;
bool statut;
struct histo * next;
}histo;
typedef struct histo * histo_pt;
struct personne{
char nom[TAILLE_NOM];
char prenom[TAILLE_PRENOM];
char numero[TAILLE_NUMERO];
long points;
long km;
time_t anciennete;
histo_pt historique;
};
typedef struct personne personne_t;
/////////////////////////////////////////////////////////////
/* Structure pour charger la liste des modele d'avion existant et leurs infos
comme une description */
typedef struct avion_load{
char modele[TAILLE_MODELE];
char description[TAILLE_DESCRIPTION];
long capacite;
struct avion_load * next;
}avion_load;
typedef struct avion_load * liste_avion;
////////////////////////////////////////////////////////////
/* Structure utiliser pour modeliser en memoire les passagers ayant deja
reserver a un jour j */
typedef struct cell_passager{
long hash;
struct cell_passager * next;
}cell_passager;
typedef struct cell_passager * liste_passager;
/* Structure en arbre pour ranger les vols a modifier en arbre AVL plus tard*/
typedef struct Noeud_vol{
char numero[TAILLE_NUMERO];
char horaire[TAILLE_DATE];
char modele[TAILLE_MODELE];
char compagnie[TAILLE_COMPAGNIE];
long distance;
long capacite;
char destination[TAILLE_DESTINATION];
long facteur_equilibre;
liste_passager passager[31];
struct Noeud_vol *droit;
struct Noeud_vol *gauche;
}Noeud_vol;
typedef struct Noeud_vol NoeudAVL;
/*****************************************************************************
DECLARATION DES VARIABLES GLOBALES
*****************************************************************************/
/* Racine de l'arbre des vols */
NoeudAVL * racine = NULL;
long rotation = 0;
/* Liste des avions charges en memoire */
liste_avion listing_avion = NULL;
/* Table de hashage */
personne_t table_hashage[TAILLE_TABLE];
/* Date de la derniere sauvegarde qui permet de dialoguer avec le thread de sauvegarde */
time_t temps_start = 0;
long avance_time = 0;
/* temps utilisé dans tout le programme comme temps courant, mit a jour par la thread */
time_t temps_courant = 0;
/* Variable pour verifier l'identification */
long identification = NON_IDENTIFIE;
/*****************************************************************************
LISTE DES DECLARATION DE FONCTIONS UTILISEES DANS LE PROGRAMME
*****************************************************************************/
/* Fonctions relatives aux arbres AVL */
long insertion_noeud(NoeudAVL *s_arbre, NoeudAVL *nouveau_noeud, NoeudAVL *pere);
long rotation_gauche(NoeudAVL *s_arbre, NoeudAVL *pere);
long rotation_droite(NoeudAVL *s_arbre, NoeudAVL *pere);
///////////////////////////////////////////////////////////////
/* Fonctions relatives aux tables de hashage */
void initialisation_table();
long code_hashage_1(char clef[]);
long code_hashage_2(char clef[]);
void insertion_element(personne_t nouvel_element);
void affichage_table();
long recherche_element(char clef[], char clef2[]);
....
....
/* Fonction des threads */
void *task_a (void *p_data);
#endif |
et plusieurs fichiers :
load_client.c
load_vol.c
...
du type :
Code:
1 2 3 4 5 6
|
#include "struct.h"
fonction...
...
... |
enfin mon makefile :
Code:
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
|
eflyer: avl.o reservation.o load_vol.o load_avions.o hash.o load_clients.o ncurses.o affichage_liste.o main.o
gcc -o eflyer.exe main.o avl.o reservation.o load_vol.o load_avions.o hash.o load_clients.o ncurses.o affichage_liste.o -lncurses -lpthread
avl.o: avl.c struct.h
gcc -c avl.c
reservation.o: reservation.c struct.h
gcc -c reservation.c
load_vol.o: load_vol.c struct.h
gcc -c load_vol.c
load_avions.o: load_avions.c struct.h
gcc -c load_avions.c
hash.o: hash.c struct.h
gcc -c hash.c
load_clients.o: load_clients.c struct.h
gcc -c load_clients.c
ncurses.o: ncurses.c struct.h
gcc -c ncurses.c
affichage_liste.o: affichage_liste.c struct.h
gcc -c affichage_liste.c
main.o: main.c struct.h
gcc -c main.c |
et malheureusement a la compilation j'ai un résultat dans ce genre la :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
gcc -c avl.c
gcc -c reservation.c
gcc -c load_vol.c
gcc -c load_avions.c
gcc -c hash.c
gcc -c load_clients.c
gcc -c ncurses.c
gcc -c affichage_liste.c
gcc -o eflyer.exe main.o avl.o reservation.o load_vol.o load_avions.o hash.o load_clients.o ncurses.o affichage_liste.o
/usr/bin/ld: multiple definitions of symbol _avance_time
main.o definition of _avance_time in section (__DATA,__data)
avl.o definition of _avance_time in section (__DATA,__data)
/usr/bin/ld: multiple definitions of symbol _identification
main.o definition of _identification in section (__DATA,__data)
avl.o definition of _identification in section (__DATA,__data)
/usr/bin/ld: multiple definitions of symbol _listing_avion
main.o definition of _listing_avion in section (__DATA,__data)
avl.o definition of _listing_avion in section (__DATA,__data)
... |
J'ai bien compris que c'est un problème de variables globales définies plusieurs fois. Pourtant j'ai bien mis les ifndef. J'ai par ailleurs vu dans la FAQ quelque chose à ce propos mais je ne comprend pas très bien comment résoudre le problème.
Enfin deuxième problème :
Voici mon main :
Code:
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
|
#include "struct.h"
void *task_a (void *p_data){
time_t temps_temp;
// Cette fonction travail uniquement sur des variables globales
while(1){
// Toutes des variables de types time_t
temps_courant = temps_courant + (time(NULL) - temps_temp);
temps_temp = time(NULL);
if(avance_time){
// Si avance time a une valeur c'est que l'on veut avance le temps de x jours
launch_save();
temps_courant = temps_courant + (86400 * avance_time);
avance_time = 0;
temps_start = temps_courant;
}
else{
// Si la différence de temps entre le temps a l'ouverture
// ou celui de la derniere sauvegarde est superieur a une journe
if( difftime(temps_courant, temps_start) > 86400){
// On lance la sauvegarde
launch_save();
temps_start = temps_courant;
}
}
}
(void) p_data;
return NULL;
}
int main(){
// Creation de la task de sauvegarde et de gestion du temps
pthread_t ta;
// Lancement de la task
pthread_create(&ta, NULL, task_a, NULL);
// Redimentionnement de la fenetre
win_size();
// Initialisation de l ecran pour ncurses
initscr();
// Activation des touches de fonctions clavier
keypad(stdscr, TRUE);
// Empeche l'impression des touches non desire
noecho();
// Lancement du programme
////////////////////////////////////////////////////////////
intro();
clear();
// Chargement des donnees en memoire et petite animation
loading();
// Lancement du menu principale
main_menu();
// On coupe ncurses proprement
endwin() ;
// On lance une petite sauvegarde
launch_save();
// Desallocation memoire de tout ce qui a ete charger
free_vol();
free_avion();
// On quitte
return(0);
} |
Le thread qui gere le temps communique avec le reste du programme par la variable globale avance_time normalement égale à 0 sauf lorsque que l'on veut avancer le temps.
Pourtant la moindre modification de la variable avance_time entraine un bus error (malgré mon problème de compilation j'ai pu tester mon programme en copiant le contenu de tous les fichiers dans un seul)
Si quelqu'un pouvait m'aider à corriger le problème se serait vraiment sympa :).
Merci d'avance.
Trivol