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 :

Erreur segmentation en multithreads


Sujet :

C

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Par défaut Erreur segmentation en multithreads
    Bonjour à tous,

    Décidément, j'ai de gros problèmes d'allocation mémoire.
    Je dois simuler un magasin et pour celà, je simule le comportement de chaque client par un thread et le comportement des caisses par trois threads (un par opération).
    Le Client remplit un tableau de taille fixe avec des nombres aléatoires, puis choisit parmi les quatre caisses celle dont la file d'attente est la moins remplie. L'accès au tableau comprenant les valeurs des files d'attente est réglé par un sémaphore. De plus, chaque caisse ne peut avoir que N/4 clients qui y attendent (N étant le nombre total de clients). En me basant sur mes précédentes aventures, j'obtiens ceci : (très long...)

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    #include <pthread.h>
    #include <semaphore.h>
    #define MAXP 50
    #define MAXC 150
    #define NBCLI 100
    #define PRIXMAX 99
    int caisse[4];//nombre de clients attendant à chaque caisse
    sem_t sem_portique, sem_acces_caisse, sem_caisse[4];//sémaphores utilisés dans la programmation
    float histo[MAXC][3];
    struct Cli
    {
    int id;
    int chariot[MAXP];
    };
     
    typedef struct Cli Client;
    /*Ls trois fonctions suivantes permettent de simuler le comportement de la caissière
    Les fonctions sont adaptées à l'utilisation par un thread de type pthread_t*/
    void* Moyenne (void* pdata)
    {
    	double* somme=malloc(sizeof(double));
    	*somme=0;
    	int* moyenne=(int*)pdata;
    	for (int i=0; i<MAXP; i++)
    	{
    		*somme+=(double)*(moyenne+i);
    	}
    	*somme/=MAXP;
    	return (void*) somme;
    }
     
    void* Quadratique(void* pdata)
    {
    	double* somme=malloc(sizeof(double));
    	*somme=0;
    	int* moyenne=(int*)pdata;
    	for (int i=0; i<MAXP; i++)
    	{
    		*somme+=(double)((*(moyenne+i))*(*(moyenne+i)));
    	}
    	*somme/=MAXP;
    	*somme=sqrt(*somme);
    	return (void*) somme;
    }
     
    void* Cube(void* pdata)
    {
    	double* somme=malloc(sizeof(double));
    	*somme=0;
    	int* moyenne=(int*)pdata;
    	for (int i=0; i<MAXP; i++)
    	{
    		*somme+=(double)((*(moyenne+i))*(*(moyenne+i))*(*(moyenne+i)));
    	}
    	return (void*) somme;
    }
    /*La procédure client utilisant les sémaphores. La fonction est utilisée par un thread.*/
    void* Client_sim(void* pdata)
    {
    	int i, idc=(int) pdata;
    	Client C;
    	C.id=idc;
    	sem_wait(&sem_portique);//Entrée du client dans le magasin si possible
    	printf("Entree du client %d \n",C.id);
    	for(i=0;i<MAXP;i++)
    	{
    		C.chariot[i]=(int)(1+rand())%(50);//remplissage du chariot du client
    	}
    	printf("Fin des achats pour le client %d \n",C.id);
    	sem_wait(&sem_acces_caisse);//Demande du client pour un accès au tableau des files des caisses
    	i=find_caisse_minimale();//Recherche et sauvegarde de la caisse la moins remplie
    	sem_post(&sem_acces_caisse);
    	sem_wait(&sem_caisse[i]);//attente à la caisse ayant la plus petite file d'attente
    	caisse_client(C.chariot, i);
    	sem_post(&sem_caisse[i]);
    	printf("Temps passe dans le magasin pour le client %d : temps \n",C.id);
    	sem_post(&sem_portique);//Sortie du client
    	free(C.chariot[]);
    }
    //Cette fonction est la seule utilisant un if. Elle retourne le numéro de la caisse ayant le plus petit nombre de 
    //clients qui y attendent. Si deux caisses ont le même nombre de clients y attendant, c'est la première qui est renvoyée.
    int find_caisse_minimale()
    {
    	int i,min=0;
    	for(i=1;i<4;i++)
    	{
    		if(caisse[min]<caisse[i])
    		{
    			min=caisse[i];
    		}
    	}
    	caisse[min]--;
    	return min;
    }
    //Cette procédure calcule le ticket d'un client et décrémente le sémaphore associé une fois le travail effectué.
    //Elle utilise la même structure que la caisse threadée du deuxième programme séquentiel.
    void caisse_client(int chariot[], int i)
    {
    	pthread_t moy, qua, cub;
    	void* un;
    	void* deux;
    	void* trois;
    	double* val;
    	pthread_create(&moy,NULL,Moyenne,chariot);
    	pthread_create(&qua,NULL,Quadratique,chariot);
    	pthread_create(&cub,NULL,Cube,chariot);
    	pthread_join(moy,&un);
    	pthread_join(qua,&deux);
    	pthread_join(cub,&trois);
    	val=(double*)un;
    	histo[i][0]=(double)*val;
    	val=(double*)deux;
    	histo[i][1]=(double)*val;
    	val=(double*)trois;
    	histo[i][2]=(double)*val;
    	free(un);
    	free(deux);
    	free(trois);
    	sem_wait(&sem_acces_caisse);
    	caisse[i]++;
    	sem_post(&sem_acces_caisse);	
    }
    int main()
    {
    	int i;
    	void* useless;
    	caisse[0]=MAXC/4;caisse[1]=MAXC/4;caisse[2]=MAXC/4;caisse[3]=MAXC/4;
    	pthread_t clients[MAXC];
    	srand(time(NULL));
    	sem_init(&sem_portique,0,NBCLI);
    	sem_init(&sem_acces_caisse,0,1);
    	for(i=0;i<4;i++)
    	{
    		sem_init(&sem_caisse[i],0,caisse[i]);
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		pthread_create(&clients[i],NULL,Client_sim,i);
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		pthread_join(useless,&clients[i]);
    		free(useless);
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		printf("Ticket du client %d : %0.4f %0.4f %0.4f \n",i,histo[i][0],histo[i][1],histo[i][2]);
    	}
    	return 0;
    }
    La compilation fonctionne bien, mais lors de l'exécution parallèle des clients, une Erreur de segmentation intervient au bout d'un moment (avant la création du dernier client).

    Exemple d'exécution (la fin de celle-ci) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Fin des achats pour le client 113 
    Temps passe dans le magasin pour le client 76 : temps 
    Temps passe dans le magasin pour le client 73 : temps 
    Temps passe dans le magasin pour le client 96 : temps 
    Entree du client 114 
    Fin des achats pour le client 114 
    Temps passe dans le magasin pour le client 105 : temps 
    Temps passe dans le magasin pour le client 102 : temps 
    Temps passe dans le magasin pour le client 88 : temps 
    Erreur de segmentation (core dumped)
    (je dois implémenter un chronomètre, mais je le ferai lorsque le programme s'exécutera comme il faut, d'où l'affichage un peu inutile...)

    Je travaille dessus depuis vendredi et commence sérieusement à en avoir marre (je suis désolé de mon manque de persévérance). Je me doute que le problème doit venir de ma fonction Client_sim, où je dois probablement mal utiliser un pointeur, mais même en reprenant tous mes pointeurs un par un, rien à faire. Je n'arrive pas à utiliser Valgrind qui pourtant pourrait probablement me sauver la vie, et j'avoue que je n'en peux plus.

    Si quelqu'un peut m'aider, je lui devrai une reconnaissance éternelle.

    Ci-joint le code du programme.

    Cordialement,

    Vrashnak
    Fichiers attachés Fichiers attachés

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur segmentation
    Par hornov dans le forum C
    Réponses: 6
    Dernier message: 18/02/2007, 01h02
  2. chaine de caractères , erreur segmentation
    Par psgman113 dans le forum C
    Réponses: 17
    Dernier message: 19/01/2007, 17h51
  3. erreur segmentation java
    Par dj cediorko dans le forum Langage
    Réponses: 1
    Dernier message: 31/12/2006, 12h30
  4. segmentation fault, multithread et debogage..
    Par jobherzt dans le forum C++
    Réponses: 3
    Dernier message: 02/08/2006, 23h39
  5. [erreur] Segmentation fault
    Par fveysseire dans le forum C
    Réponses: 11
    Dernier message: 15/06/2006, 14h44

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