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

Linux Discussion :

Problème avec 2 threads : l'un bloque l'autre


Sujet :

Linux

  1. #1
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut Problème avec 2 threads : l'un bloque l'autre
    Bonjour tout le monde,

    J'ai un petit soucis avec des threads en C.

    Je dois développer un petit chat, en local, et utiliser des threads.

    J'ai donc deux executables, un serveur, qui se lance comme démon et qui reçoit tous les messages des différents utilisateurs dans une file de message qu'il créé lui-même et qui les renvoit dans chaque file propre à un client.
    Comme ça, tous les clients reçoivent les messages de tout le monde.
    De ce côté-là, je n'ai pas de soucis.
    Pour l'instant, pas de thread à gérer, j'ai une boucle infinie dans le serveur qui lui permet d'être toujours en attente de message dans sa file et qui les traitent quand il en reçoit !

    Pour mon client, il doit d'abord récupérer la file du serveur, ensuite il se créé sa propre file et puis il envoit son pseudo et son file_id au serveur, qui vérifie le pseudo et lui renvoit un message sur la file du client pour l'autoriser à entrer ou non.
    Après, je lance 2 threads. Un qui est en attente de messages sur sa file (et qui doit recevoir tous les messages des autres clients) et un qui permet d'envoyer des messages et qui est donc dans l'attente de saisie d'une chaine au clavier.

    Seulement, si je créé le thread d'envoi en premier, je peux envoyer des messages mais n'en reçois pas !
    Alors que si je fais l'inverse, je peux en recevoir mais pas en créer ...

    En fait, les threads ne semblent pas s'exécuter en parallèle, alors que c'est quand même leur but, si je ne me trompe pas ...

    Voilà, si quelqu'un avait une idée ...

    Je vous remercie par avance et vous mets le code de mon chat.c (qui correspond au client)

    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
    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
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    #include "file.h"
    #include <errno.h>
     
    /** Definition des variables globales : **/
    static char* PSEUDO;
    static int MSQID_SERV;
    static int MSQID_RCV;
    static key_t cle_serv;
    static key_t cle_client;
     
    /* Declaration de la fenetre */
    WINDOW *f_haut, *f_bas;
     
     
     
    WINDOW *creation_fenetre(int n, int d, char *t){
     
    	WINDOW *cadre;
     
    	WINDOW *w;
     
     
     
    	cadre = newwin(n, COLS, d, 0);
     
    	box(cadre, 0,0);
     
    	mvwprintw(cadre,0,COLS/2-strlen(t)/2,t);
     
     
     
    	wrefresh(cadre);
     
     
     
    	w = newwin(n-2, COLS-2, d+1, 1);
     
    	idlok(w, TRUE);
     
    	scrollok(w, TRUE);
     
    	wclear(w);
     
     
     
    	wrefresh(w);
     
     
     
    	return w;
     
    }
     
     
     
     
    void connexion(){
    	message *mmsg;
    	mmsg = malloc(sizeof(struct message));
    	(*mmsg).mtype = 1;
    	strcpy((*mmsg).mtext, ">> ");
    	strcat((*mmsg).mtext, PSEUDO);
    	strcat((*mmsg).mtext, TXT_CONNEXION_AUTRE);
    	strcpy((*mmsg).pseudo, PSEUDO);
    	(*mmsg).msqid = MSQID_RCV;
    	msgsnd(MSQID_SERV, mmsg, sizeof(struct message), MSG_NOERROR);
    	return;
    }
     
     
    /* Fonction qui envoie un message vers le serveur */
    void envoi_msg(char* msg){
    	message *mmsg;
    	mmsg = malloc(sizeof(struct message));
    	(*mmsg).mtype = 10;
    	strcpy((*mmsg).mtext, PSEUDO);
    	strcat((*mmsg).mtext, DIRE);
    	strcat((*mmsg).mtext, msg);
    	strcpy((*mmsg).pseudo,PSEUDO);
    	(*mmsg).msqid = MSQID_RCV;
    	msgsnd(MSQID_SERV, mmsg, sizeof(message), MSG_NOERROR);
    	return;
    }
     
     
     
    void deconnexion(){
    	message *mmsg;
    	mmsg = malloc(sizeof(struct message));
    	(*mmsg).mtype = 3;
    	strcpy((*mmsg).mtext, "<< ");
    	strcat((*mmsg).mtext, PSEUDO);
    	strcat((*mmsg).mtext, TXT_DECONNEXION_AUTRE);
    	strcpy((*mmsg).pseudo,PSEUDO);
    	(*mmsg).msqid = MSQID_RCV;
    	msgsnd(MSQID_SERV, mmsg, sizeof(message), MSG_NOERROR);
    	return;
    }
     
     
    /* Fonction permettant l'envoi des messages */
    void * envoi_messages(){
    	message *mmsg;
    	mmsg = malloc(sizeof(struct message));
    	char *msg;
    	msg = malloc(sizeof(char)*255);
    	wgetstr(f_bas, msg);
    	while(strcmp(TXT_QUIT,msg) != 0){
    		(*mmsg).mtype = 4;
    		strcpy((*mmsg).mtext,msg);
    		/* Envoi du message dans la file */
    		envoi_msg(msg);
    		werase(f_bas);
    		wgetstr(f_bas, msg);
    	}
    	/* Deconnexion de l'utilisateur ! */
    	deconnexion();
    	pthread_exit(0);
    	return 0;
    }
     
     
    /* Fonction permettant la reception des messages */
    void * reception_messages(){
    	message *msgp;
    	msgp = malloc(sizeof(struct message));
    	int msgsz = sizeof(struct message);
    	while(1){
    		msgrcv(MSQID_RCV,msgp,msgsz,0,0);
    		switch((*msgp).mtype){
    			case 4:
    				waddstr(f_haut,"Message recu : ");
    				waddstr(f_haut,(*msgp).mtext);
    				waddstr(f_haut,"\n");
    				wrefresh(f_haut);
    				break;
    			default:
    				waddstr(f_haut,"ICI \n");
    				wrefresh(f_haut);
    				break;
    		}
    	}
    	pthread_exit(0);
    	return 0;
    }
     
     
     
     
    /* Fonction principale du programme chat */
    int main(int argc, char* argv[]){
    	struct msqid_ds *stat;
    	stat = malloc(sizeof(struct msqid_ds));
    	message *mmsg;
    	mmsg = malloc(sizeof(struct message));
    	PSEUDO = malloc(sizeof(char)*255);
    	int i;
     
    	/* Test des parametres */
    	if(argc != 3){
    		printf("%s",USAGE_CHAT);
    		return -1;
    	}
     
    	if(strcmp(argv[1], "-p") != 0){
    		return -1;
    	}
     
    	/* Recuperation du pseudo dans la variable globale PSEUDO */
    	strcpy(PSEUDO, argv[2]);
     
    	/* Creation de la cle du serveur */
    	cle_serv = ftok(KEY_FILE,KEY_ID_SERV);
     
    	/* Recuperation de l'identificateur de la file de messages du serveur */
    	MSQID_SERV = msgget(cle_serv, IPC_STAT);
     
    	printf("File serveur : %i\n",MSQID_SERV);
    	/* Si aucune file de message n'est trouvee, on quitte */
    	if(MSQID_SERV == -1){
    		printf("Aucun serveur trouve !!\n");
    		exit(1);
    	}
     
    	/* On cree une file de messages du client (unique a chaque client) */
    	i = 1;
    	cle_client = ftok(KEY_FILE,i);
    	MSQID_RCV = msgget(cle_client, IPC_STAT);
    	while(MSQID_RCV != -1){
    		i++;
    		cle_client = ftok(KEY_FILE,i);
    		MSQID_RCV = msgget(cle_client, IPC_STAT);
    	}
    	MSQID_RCV = msgget(cle_client, IPC_CREAT | 0666);
    	if(MSQID_RCV == -1){
    		printf("Erreur lors de la creation de la file du client !\n");
    		printf("Errno : %i \n",errno);
    		exit(0);
    	}
    	printf("Ma file est : %i\n", MSQID_RCV);
     
    	/* Si on a trouve la file de messages du serveur, on etablit la connexion */
    	connexion();
     
     
    	/* Attente du message du serveur pour confirmation de connexion */
    	msgrcv(MSQID_RCV,mmsg,sizeof(struct message),0,3);
    	if((*mmsg).msqid < 0){
    		printf("Le pseudo '%s' est deja utilisé !\nVeuillez en essayer un autre ou tentez de vous reconnecter plus tard ...\n",(*mmsg).pseudo);
    		exit(0);
    	}
     
     
    	initscr();
     
    	noecho();
     
    	cbreak();
     
     
     
    	f_haut = creation_fenetre(18,0,"MESSAGES : ");
     
    	f_bas = creation_fenetre(6,18,"ENVOI DE MESSAGE : ");
     
     
    	echo();
     
    	/* Declaration des threads */
    	pthread_t my_thread_snd;
    	pthread_t my_thread_rcv;
     
    	/* Creation du thread pour l'envoi des messages */
    	if(pthread_create(&my_thread_snd, NULL, envoi_messages, NULL) < 0){
    		printf("pthread_create erreur for thread 1 \n");
    		exit(1);
    	}
     
     
    	/* Creation du thread pour la reception des messages */
    	if(pthread_create(&my_thread_rcv, NULL, reception_messages, NULL) < 0){
    		printf("pthread_create erreur for thread 1 \n");
    		exit(1);
    	}
     
    	pthread_join(my_thread_rcv, NULL);
    	pthread_join(my_thread_snd, NULL);
     
     
     
    	endwin();
    	return 0;
    }

  2. #2
    Membre averti Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Points : 414
    Points
    414
    Par défaut
    salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pthread_join(my_thread_rcv, NULL);
    	pthread_join(my_thread_snd, NULL);
    je pense que les threads doivent être détaché du thread principale .....
    "La créativité est faites d'attention et de respect pour les petits faits de la vie."

  3. #3
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Non.

    Si je les détache, je récupère la main sur mon terminal et je ne peux plus rien faire ...

    Si je détache seulement l'envoi, ou seulement la réception, je peux envoyer mais je reçois pas ... Ou seulement que je termine les envois (c'est-à-dire quand je saisis ma chaine de fin d'envoi) !!


  4. #4
    Membre averti Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Points : 414
    Points
    414
    Par défaut
    Si je les détache, je récupère la main sur mon terminal et je ne peux plus rien faire ...
    c'est le but de détaché le thread, non ?

    et quesque tu veus des thread, ils ont leurs propres taches a faire, et tu peut récuperer les messages par les queues des message...
    "La créativité est faites d'attention et de respect pour les petits faits de la vie."

  5. #5
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par cmoibal Voir le message
    c'est le but de détaché le thread, non ?

    et quesque tu veus des thread, ils ont leurs propres taches a faire, et tu peut récuperer les messages par les queues des message...
    Oui, les threads ont leur propre tâche à faire, mais ça ne doit pas terminer mon programme si ces threads sont toujours en exécution !!!

    Et j'attends d'eux qu'ils s'exécutent en parallèle ...
    Mais ça ne semble pas être le cas. Un seul s'exécute !!

    C'est tout de même bizarre.
    Je pensais que quand on créé un thread, il s'exécute en parallèle, en même temps que la suite du main, mais c'est pas le cas chez moi ...

    Ca pourrait être un problème d'OS ?

  6. #6
    Membre averti Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Points : 414
    Points
    414
    Par défaut
    c'est vrai que chaque système a sa propre gestion des thread, mais normalement toutes les gestions envisage le parallisme des threads... alors, je pense pas que sa soit du système .


    Pour l'instant, pas de thread à gérer, j'ai une boucle infinie dans le serveur qui lui permet d'être toujours en attente de message dans sa file et qui les traitent quand il en reçoit !
    Peut être que le problème c'est dans le serveur, peut tu ajouter des thread pour traiter les messages reçu....
    Je pense que le serveur est occupé a faire une seule tache a la foix, c'est pour ca que le client ne peut pas envoyer plusieur message au serveur ....
    "La créativité est faites d'attention et de respect pour les petits faits de la vie."

  7. #7
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Si, du côté du serveur tout se passe bien, sans thread.
    Car il est en attente de messages et quand il en reçoit un, il parcourt la liste des connectes pour leur envoyer le message et après, il retourne dans un état d'attente de réception de message !

    Pour preuve, j'avais compilé deux exécutables pour le client, un client1 pour lequel le thread d'envoi était avant celui de réception et un client2 pour lequel les threads étaient créés dans l'ordre inverse.

    Et là, mon client1 pouvait envoyer tous les messages qu'il voulait et le client2 les recevait !

    Mais client1 ne recevait rien et client2 n'avait pas la main pour envoyer !!

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par pontus21 Voir le message
    Je vous remercie par avance et vous mets le code de mon chat.c (qui correspond au client)
    Ne compile pas. Il manque "file.h". J'ai inclus <curses.h>, mais :

    'key_t' inconnu
    'message' inconnu

    etc. On ne peut rien tester.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Voici le file.h qui contient différents include


    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
    /** Appels des differents 'include' **/
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/msg.h>
    #include <pthread.h>
    #include <ncurses.h>
     
     
    /** Definition des differents messages : **/
    #define USAGE_CHAT "ERREUR ! \nUsage : chat -p <pseudo> \n"
    #define TXT_CONNEXION_AUTRE " a rejoint le chat ! \n"
    #define TXT_CONNEXION "## Bienvenue sur le chat !\n"
    #define TXT_DECONNEXION_AUTRE " a quitte le chat ! \n"
    #define TXT_DECONNEXION "## Au revoir et a bientot sur le chat !\n"
    #define DIRE " dit : "
     
    /** Definition des codes des diffrentes touches : **/
    #define COLS 80
     
    #define LINES 24
     
    #define CTRL_D 15
     
    #define CTRL_E 5
     
     
    /** Definition des constantes pour la creation de la file de messages du serveur : **/
    #define KEY_FILE "/home/maxime/Desktop/systeme/projet_Max/key"
    #define KEY_ID_SERV 54918
     
     
    /** Definition de differentes autres constantes : **/
    #define TXT_QUIT "/q"
    #define TAILLE_TXT 255
    #define TAILLE sizeof(struct message)
     
     
    /** Declaration des differentes structures : **/
    /* Structure des messages qui constitueront la file de messages */
    typedef struct message{
    	long mtype;
    	char mtext[255];
    	char pseudo[25];
    	int msqid;
    }message;
     
    /* Structure de la liste des connectes */
    typedef struct Tlist{
    	int msqid;
    	char pseudo[25];
    	long date;
    	struct Tlist * next;
    }Tlist;

    Voici aussi le servchat.c, par la meme occasion :

    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
    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
    #include "file.h"
     
    /* Variable globale contenant le nombre de connectes */
    static int NB_CONN;
     
     
    /* Fonction principale du programme servchat */
    int main(int argc, char* argv[]){
    	/* Liste des connectes */
    	Tlist *list = NULL, *tmp = NULL, *lparc = NULL;
    	/* Structure de type msqid_ds */
    	struct msqid_ds *stat;
    	stat = malloc(sizeof(struct msqid_ds));
    	/* Identificateur de la file */
    	int msqid;
    	/* Booleen pour la recherche du client dans la liste */
    	int trouve;
     
    	/* Initialisation du nombre de connectes a 0 */
    	NB_CONN = 0;
     
    	message *msgp, *mmsg;
    	msgp = malloc(sizeof(struct message));
    	mmsg = malloc(sizeof(struct message));
    	int msgsz = sizeof(struct message);
     
    	/* Test des parametres */
    	if(argc != 1 && argc != 3 && argc != 5){
    		printf("ERREUR ! \nUsage : servchat [ -n <nbmaxi> -t <timeout> ] \n");
    		exit(EXIT_FAILURE);
    	}
     
    	/* Creation de la cle */
    	key_t cle;
    	cle = ftok(KEY_FILE,KEY_ID_SERV);
     
    	/* On teste si la file de messages du serveur existe */
    	msqid = msgget(cle, IPC_STAT);
    	if(msqid != -1){
    		if(msgctl(msqid, IPC_RMID, stat) == -1){
    			perror("Erreur lors de la suppression de la file de messages du serveur : \n");
    			exit(EXIT_FAILURE);
    		}
    	}
     
    	/* Creation d'un identificateur de file de messages */
    	msqid = msgget(cle, IPC_CREAT | 0666);
    	printf("Queue : %i\n",msqid);
     
    	printf("Chat lancé ... \n");
     
    	/* Attente infinie */
    	while(1){
    		msgrcv(msqid,msgp,msgsz,0,0);
    		switch((*msgp).mtype){
    			case 1: /* Demande de connexion d'un utilisateur */
    				printf("Type du message recu : %li\n",(*msgp).mtype);
    				printf("Id de la file recu : %i\n",(*msgp).msqid);
    				printf("Connexion de : %s\n",(*msgp).pseudo);
    				/* On verifie si le pseudo est deja connecte ou non */
    				lparc = list;
    				trouve = 0;
     
    				strcpy((*mmsg).pseudo,(*msgp).pseudo);
    				strcpy((*mmsg).mtext, "");
    				(*mmsg).mtype = 3;
     
    				while(lparc && !trouve){
    					printf("Comparaison de '%s' avec '%s'\n",lparc->pseudo, (*msgp).pseudo);
    					if( strcmp(lparc->pseudo, (*msgp).pseudo) == 0 ){
    						printf("Connexion refusee, le pseudo '%s' est deja pris !\n",lparc->pseudo);
    						trouve = 1;
    						(*mmsg).msqid = -1;
    						msgsnd((*msgp).msqid, mmsg, sizeof(struct message), MSG_NOERROR);
    					}
    					lparc = lparc->next;
    				}
    				if(!trouve){
    					/* Ajout du connecte dans la liste */
    					NB_CONN++;
    					printf("Ajout du pseudo '%s' dans la liste !\n",(*msgp).pseudo);
    					if(tmp == NULL){
    						list = tmp = malloc(sizeof(Tlist));
    					}else{
    						tmp->next = malloc(sizeof(Tlist));
    						tmp = tmp->next;
    					}
    					tmp->next = NULL;
    					tmp->msqid = (*msgp).msqid;
    					strcpy(tmp->pseudo,(*msgp).pseudo);
    					tmp->date = time(NULL);
     
    					/* Affichage de la liste des connectes */
    					lparc = list;
    					printf("Liste : \n");
    					while(lparc){
    						printf(" -- %s\n",lparc->pseudo);
    						lparc = lparc->next;
    					}
    					lparc = NULL;
     
    					(*mmsg).msqid = 1;
    					msgsnd((*msgp).msqid, mmsg, sizeof(struct message), MSG_NOERROR);
    				}
    				break;
    			case 3: /* Deconnexion de l'utilisateur */
    				trouve = 0;
    				Tlist **tmp1 = &list;
    				Tlist *prev = *tmp1;
    				while(*tmp1 && !trouve){
    					if( strcmp((*tmp1)->pseudo, (*msgp).pseudo) == 0 ){
    						trouve = 1;
    						if((*tmp1)->next){
    							Tlist *tmp2 = *tmp1;
    							*tmp1 = tmp2->next;
    							free(tmp2);
    						}else{
    							free(*tmp1);
    							prev->next = NULL;
    						}
    					}else{
    						prev = *tmp1;
    						tmp1 = &(*tmp1)->next;
    					}
    				}
    				if(trouve){
    					NB_CONN--;
    					printf("<< '%s' s'est deconnecte\n",(*msgp).pseudo);
    				}else{
    					printf("Erreur lors de la deconnexion de '%s' !\nPseudo non present dans la liste des connecte\n",(*msgp).pseudo);
    				}
    				/* Affichage de la liste des connectes */
    				lparc = list;
    				printf("Liste : \n");
    				while(lparc){
    					printf(" -- %s\n",lparc->pseudo);
    					lparc = lparc->next;
    				}
    				lparc = NULL;
    				if(NB_CONN == 0){
    					list = NULL;
    					tmp = NULL;
    					lparc = NULL;
    				}
    				break;
    			default:				
    				printf("%s",(*msgp).mtext);
    				/* Creation du message */
    				message *mmsg;
    				mmsg = malloc(sizeof(struct message));
    				(*mmsg).mtype = 4;
    				strcpy((*mmsg).mtext, (*msgp).mtext);
    				(*mmsg).msqid = 0;
    				/* Parcours de la liste des connectes pour leur envoyer le message a chacun */
    				lparc = list;
    				while(lparc){
    					msgsnd(lparc->msqid, mmsg, sizeof(struct message), MSG_NOERROR);
    					printf("Message envoye sur la file %i ; a %s\n",lparc->msqid,lparc->pseudo);
    					lparc = lparc->next;
    				}
    				break;
    		}
     
    	}
     
    	return 0;
    }
    Voilà.

    Normalement, vous devez avoir toutes les données.

    Merci d'avance, parce que là, je ne vois vraiment pas ...

  10. #10
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Est-il possible de renommer le titre du "thread"
    pour mettre "Problème avec 2 threads : l'un bloque l'autre" ??

    Merci d'avance

  11. #11
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Citation Envoyé par pontus21 Voir le message
    Est-il possible de renommer le titre du "thread"
    pour mettre "Problème avec 2 threads : l'un bloque l'autre" ??

    Merci d'avance
    En principe tu peux le faire en éditant ton premier message.
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  12. #12
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par hegros Voir le message
    En principe tu peux le faire en éditant ton premier message.
    Exact, merci !

    J'ai l'impression que ça vient d'Ubuntu, mon problème, ou alors de mon compilateur ...
    J'ai repris un code trouvé sur internet pour faire un test de threads et j'ai pas le résultat escompté ...

    Quelqu'un pour m'aider ...
    Please !!!

  13. #13
    Membre à l'essai
    Inscrit en
    Décembre 2007
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 16
    Points : 22
    Points
    22
    Par défaut
    Bonjour,

    j'ai regardé rapidement le code, et je m'interroge sur les fonctions "waddstr" et "wrefresh". Je ne les connais pas et suppose fortement qu'il s'agit de fonctions liées à l'interface graphique.

    J'ai déjà eu des problèmes avec des threads manipulant une même interface graphique : il faut éviter.

    Solution : UN SEUL THREAD manipule l'interface graphique, c'est celui qui a créé cette interface graphique (ici, c'est le père).
    Les autres threads (fils) ne font que communiquer des informations au père (par la fonction pipe par exemple, qui est assez simple d'utilisation). Et c'est le père qui se charge d'afficher les informations.

    Pour tester rapidement si j'ai raison, ce que tu peux faire c'est envoyer les infos sur la console en parallèle à waddstr et wrefresh (avec un vulgaire echo) ainsi tu verrais si effectivement tes threads sont interbloqués ou pas.

  14. #14
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    J'ai déjà testé ce que tu me propose, avec de simples printf mais c'est le même problème, un des deux threads (celui lancé en premier) bloque l'autre.

    Finalement, j'ai essayé mon code à l'école, après avoir demandé aux ingénieurs système d'installer la librairie ncurses ... Et ça fonctionne !!

    De plus, mon code (peut-être pas celui posté, car je l'ai modifié un peu depuis) ne gère chaque fenêtre qu'à travers un seul thread. Le thread d'envoi gère la saisie sur la fenêtre du bas et le thread de reception gère l'affichage des messages reçus dans la fenêtre du haut.

    Le problème vient donc de mon pc.
    Je ne sais pas si c'est un problème matériel ou logiciel ...

    Bref, pour le moment, je vais me concentrer à terminer mon projet, que je dois rendre samedi et ensuite regarder de plus près pour savoir quel est mon problème avec mon pc ...

Discussions similaires

  1. Problème avec un thread (débutant en thread)?
    Par Jayceblaster dans le forum C#
    Réponses: 10
    Dernier message: 17/01/2007, 11h01
  2. Problèmes avec les thread et les pointeurs
    Par raspac dans le forum POSIX
    Réponses: 2
    Dernier message: 22/10/2006, 17h35
  3. [BOOST] Problème avec les threads
    Par SOAD08 dans le forum Dev-C++
    Réponses: 7
    Dernier message: 08/10/2006, 10h23
  4. Réponses: 1
    Dernier message: 08/08/2006, 15h39
  5. Réponses: 5
    Dernier message: 10/05/2005, 10h22

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