Souci de programmation c

Fermé
gamaliel - 20 nov. 2009 à 18:08
 Gamaliel - 21 nov. 2009 à 00:58
Bonjour, voici pas mal de temps que je me casse la tête sur un code pour modéliser le fonctionnement d'une taverne, je vois assez bien comment m'y prendre il me semble. Le terminal compile sans problème mais quand je le lance j'ai une erreur que je ne comprends pas du tout (il n'y a qu'un seul scanf qui semble fonctionner mais le programme veut que lui entre deux valeurs et puis j'ai le menu de base qui s'affiche à chaque fois au lieu d'entrer dans les sous menus) et vu que le terminal considère que le code est bon, il ne m'aide pas beaucoup...

Si quelqu'un sait prendre 5 minutes pour copier le code, le lancer et me dire s'il voit d'où pourrait provenir mon problème ca m'aiderait beaucoup...

D'avance merci

#include <stdio.h> //GREGUOR SAMUEL Ma1 IG
#include <stdlib.h>
#include <sys/sem.h>
#include <pthread.h>
#include <sys/shm.h>
#include <signal.h>/*
#include <sys/time..h>*/
#include <sys/types.h>
#include <sys/ipc.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* l'union semun est définie par l'inclusion de <sys/sem.h> */
#else
/* d'après X/OPEN il faut la définir nous-mêmes */
union semun {
int val; /* valeur pour SETVAL */
struct semid_ds *buf; /* buffer pour IPC_STAT, IPC_SET */
unsigned short *array; /* table pour GETALL, SETALL */
/* Spécificité Linux : */
struct seminfo *__buf; /* buffer pour IPC_INFO */
};
#endif

int down(int sem_id, int sem_num)
{
struct sembuf sem_op;
sem_op.sem_num=sem_num;
sem_op.sem_op=-1;
sem_op.sem_flg=0;

if(semop(sem_id, &sem_op, 1) == -1) return -1;
else return 0;
}

int up(int sem_id, int sem_num)
{
struct sembuf sem_op;
sem_op.sem_num=sem_num;
sem_op.sem_op=+1;
sem_op.sem_flg=0;

if(semop(sem_id, &sem_op, 1) == -1) return -1;
else return 0;
}

int initialize(int sem_id, int sem_num, int init)
{
union semun semunion;
semunion.val=init;
if(semctl(sem_id,sem_num,SETVAL,semunion) == -1) return -1;
else return 0;
}

struct commande
{
int pid_groupe_clients;
int nbre_biere;
int nbre_cafe;
};

struct commande com;

void *client(void *i)
{
// choix de la boisson
srand(time(NULL));
float a = (float)rand()/RAND_MAX;
int boisson = a*2;

if(boisson==0)
{
com.nbre_biere = com.nbre_biere+1;
}
else
{
com.nbre_cafe = com.nbre_cafe+1;
}
}


void groupe_client(int nbre_client)
{
//créer manuellement à la demande de l'utilisateur via le main (chaque client = un thread indépendant : choix aléatoire de la boisson et remplissage du ticket de commande)

int i,b=0,c=0;
pthread_t id[nbre_client];
com.pid_groupe_clients = getpid();
com.nbre_biere =0;
com.nbre_cafe =0;

for (i=0;i<nbre_client;i++)
{
pthread_create(&id[i], NULL, client, &i);
pthread_join(id[i], NULL);
}
}


int main(int argc, char *argv[])
{
//menu principal et création des groupes de clients
int i,j,n,p,p1,nbre_client,shmid,nbre_table,nbre_chaise_par_table,semid,semidd;
int * table;
nbre_table=atoi(argv[1]); //création des tables et des chaises grâce aux arguments de argv par une mémoire partagée
nbre_chaise_par_table=atoi(argv[2]);
//int *table[nbre_table];


shmid = shmget(1337, sizeof(int) * nbre_table, IPC_CREAT|0660);
table = (int *)shmat(shmid, NULL, SHM_R | SHM_W);

semid = semget(64536, 1, IPC_CREAT|0660); // un sémaphore global pour les tables
initialize(semid,0,1);

semidd = semget(1234, nbre_table, IPC_CREAT|0660); //1 sémaphore par table pour les chaises

down(semid,0);
for(i=0;i<nbre_table;i++)
{
table[i]=1;
initialize(semidd,i,nbre_chaise_par_table);
}
up(semid,0);

p=fork();
if(p==-1)
{
printf("Il y a eu une erreur pour la création du serveur\n");
}
if(p==0)
{
//garcon
do
{

}while(n!=0);
}
if (p>0)
{
do
{
printf("Bonjour, que se passe-t-il dans la taverne?\n");
printf("1 : Un groupe de clients entre dans la taverne\n");
printf("0 : Plus rien..., il est tard et la taverne ferme\n");
scanf("%d\n",&n);
printf("entree n : %d\n",n);

if(n==1)
{
p1=fork();
if(p1==-1)
{
printf("Il y a eu une erreur pour l'arrivée du groupe de client, la porte doit etre fermee...\n");
}
if(p1==0)
{
//groupe_client
printf("Combien de clients y a-t-il dans le groupe?\n");
scanf("%d\n",&nbre_client);

down(semid,0);
for(i=0;i<nbre_table;i++)
{
if (table[i]==1)
{
table[i]=0;
printf("Les clients s'asseillent à la table %d\n",i);
for(j=0;j<n;j++)
{
down(semidd,i);
printf("Le client %d trouve une chaise à la table %d\n",j,i);
if(down(semidd,i)!=0)
{
if(i<nbre_table-1)
{
down(semidd,i+1);
printf("Le client %d trouve une chaise à la table %d\n",j,(i+1));
}
else
{
printf("Il n'y a plus assez de chaise disponisble car toutes les tables sont occupées\n");
break;
}
}
}
break;
}
}
up(semid,0);

groupe_client(nbre_client);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NE PAS OUBLIER DE FAIRE LA LIBÉRATION DES TABLES !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
}
else if (n==0)
{
printf("He bien, bonne nuit alors\n");
exit(0);
}
}while(n!=0);
}
}

4 réponses

Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 660
20 nov. 2009 à 22:17
je veux bien, mais si tu remets ton code avec les balises code (bouton à droite de gras italique soulignée), car sans les espacements d'indentation j'ai du mal à le lire, alors chercher un bug dedans, ça ne m'enchante pas vraiment.

Merci!
0
Voilà, j'espère que c'est cela que tu voulais, en tout cas merci de bien vouloir jeter un oeil

#include <stdio.h>												
#include <stdlib.h>
#include <sys/sem.h>
#include <pthread.h>
#include <sys/shm.h>
#include <signal.h>/*
#include <sys/time..h>*/
#include <sys/types.h>
#include <sys/ipc.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
       /* l'union semun est définie par l'inclusion de <sys/sem.h> */
#else
       /* d'après X/OPEN il faut la définir nous-mêmes */
       union semun {
             int val;                  /* valeur pour SETVAL */
             struct semid_ds *buf;     /* buffer pour IPC_STAT, IPC_SET */
             unsigned short *array;    /* table  pour GETALL, SETALL */
                                       /* Spécificité Linux : */
             struct seminfo *__buf;    /* buffer pour IPC_INFO */
       };
#endif

int down(int sem_id, int sem_num)
{
	struct sembuf sem_op;
	sem_op.sem_num=sem_num;
	sem_op.sem_op=-1;
	sem_op.sem_flg=0;
	
	if(semop(sem_id, &sem_op, 1) == -1) return -1;
	else return 0;
}

int up(int sem_id, int sem_num)
{
	struct sembuf sem_op;
	sem_op.sem_num=sem_num;
	sem_op.sem_op=+1;
	sem_op.sem_flg=0;
	
	if(semop(sem_id, &sem_op, 1) == -1) return -1;
	else return 0;
}

int initialize(int sem_id, int sem_num, int init)
{
	union semun semunion;
	semunion.val=init;
	if(semctl(sem_id,sem_num,SETVAL,semunion) == -1) return -1;
	else return 0;	
}

struct commande
{
	int pid_groupe_clients;
	int nbre_biere;
	int nbre_cafe;
};

struct commande com;

void *client(void *i)
{
	// choix de la boisson
	srand(time(NULL));
	float a = (float)rand()/RAND_MAX;
	int boisson = a*2;
	
	if(boisson==0)
	{
		com.nbre_biere = com.nbre_biere+1;
	}
	else
	{
		com.nbre_cafe = com.nbre_cafe+1;
	}
}


void groupe_client(int nbre_client)
{
	//créer manuellement à la demande de l'utilisateur via le main (chaque client = un thread indépendant : choix aléatoire de la boisson et remplissage du ticket de commande)
	
	int i,b=0,c=0;			
	pthread_t id[nbre_client];
	com.pid_groupe_clients = getpid();
	com.nbre_biere =0;
	com.nbre_cafe =0;			
	
	for (i=0;i<nbre_client;i++)
	{
		pthread_create(&id[i], NULL, client, &i);
		pthread_join(id[i], NULL);	
	}
}


int main(int argc, char *argv[])
{
															//menu principal et création des groupes de clients
	int i,j,n,p,p1,nbre_client,shmid,nbre_table,nbre_chaise_par_table,semid,semidd,flag;
	int * table;
	nbre_table=atoi(argv[1]); 											//création des tables et des chaises grâce aux arguments de argv par une mémoire partagée
	nbre_chaise_par_table=atoi(argv[2]);
	//int *table[nbre_table];
	
	
	shmid = shmget(1337, sizeof(int) * nbre_table, IPC_CREAT|0660);
	table = (int *)shmat(shmid, NULL, SHM_R | SHM_W);								
	
	semid = semget(64536, 1, IPC_CREAT|0660);									// un sémaphore global pour les tables
	initialize(semid,0,1);
	
	semidd = semget(1234, nbre_table, IPC_CREAT|0660);								//1 sémaphore par table pour les chaises 
	
	down(semid,0);
	for(i=0;i<nbre_table;i++)
	{
		table[i]=1;
		initialize(semidd,i,nbre_chaise_par_table);
	}
	up(semid,0);
	
	p=fork();
	if(p==-1)
	{
		printf("Il y a eu une erreur pour la création du serveur\n");
	}
	if(p==0)
	{
		//garcon
		do
		{
		
		}while(n!=0);	
	}
	if (p>0)
	{
		do
		{
			printf("Bonjour, que se passe-t-il dans la taverne?\n");
			printf("1 : Un groupe de clients entre dans la taverne\n");
			printf("0 : Plus rien..., il est tard et la taverne ferme\n");
			scanf("%d\n",&n);
			printf("entree n : %d\n",n);
		
			if(n==1)
			{
				p1=fork();
				if(p1==-1)
				{
					printf("Il y a eu une erreur pour l'arrivée du groupe de client, la porte doit etre fermee...\n");
				}
				if(p1==0)
				{
					//groupe_client
					printf("Combien de clients y a-t-il dans le groupe?\n");
					scanf("%d\n",&nbre_client);
					nbre_client=5;
					flag=0;
					down(semid,0);
					for(i=0;i<nbre_table;i++)
					{
						if (table[i]==1)
						{
							table[i]=0;
							flag=1;
							printf("Les clients s'asseillent à la table %d\n",i);
							up(semid,0);
							for(j=0;j<n;j++)
							{
								down(semidd,i);
								printf("Le client %d trouve une chaise à la table %d\n",j,i);
								if(down(semidd,i)!=0)
								{
									if(i<nbre_table-1)
									{
										down(semidd,i+1);
										printf("Le client %d trouve une chaise à la table %d\n",j,(i+1));
									}
									else
									{
										printf("Il n'y a plus assez de chaise disponisble car toutes les tables sont occupées\n");
										break;		
									}
								}
							}
							break;						
						}
					}
					if(flag==0)
					{
						printf("Pas de table disponible\n");
						up(semid,0);
					}
										
					groupe_client(nbre_client);
					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NE PAS OUBLIER DE FAIRE LA LIBÉRATION DES TABLES !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				}
			}
			else if (n==0)
			{
				printf("He bien, bonne nuit alors\n");
				exit(0);
			}
		}while(n!=0);	
	}
}
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 660
21 nov. 2009 à 00:30
oui c'est ce que je voulais, c'est beaucoup mieux pour copier coller dans l'éditeur.

je ne peux pas le compiler, tu utilises des biblios que je n'ai pas. et en lisant ton code tu as des "spécificités linux", désolé ,je ne peux rien faire ;)

sinon :

		//garcon
		do
		{
		
		}while(n!=0);


j'ai des doutes quant à l'utilité de ce bout de code, et par contre des certitudes quant à sa capacité à faire que le programme se bloque ^^
0
Ok merci quand même mais je pense que ce n'est pas du à ça parce que j'ai essayé de faire tourner le programme en mettant ce bout de code en commentaire mais ca ne change rien snif

Bon je vais continuer à chercher...

Bonne soirée
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 660
21 nov. 2009 à 00:53
ok, mais même, lorsqu'on traque des bugs et qu'on trouve quelquechose qui est susceptible d'en poser, autant corriger ça. ça évitera les problèmes plus tard ;)

tester n, alors que n n'est même pas initialisé peut causer des bugs. il ne faut pas mettre ce test comme ça, ça n'a pas de sens.

ensuite, ce n'est toujours pas la source du problème bien sûr mais :
					printf("Combien de clients y a-t-il dans le groupe?\n");
					scanf("%d\n",&nbre_client);
					nbre_client=5;


c'est voulu ?
0
Non c'est un oubli de ma part, il doit nbre_client=5 doit disparaitre mais je me suis rendu compte qu'il y a un souci parce que quand on a un scanf il demande une première fois la valeur, et une fois rentrée, il ne réagit pas tant qu'on entre pas une deuxieme valeur et je comprends pas vraiment pourquoi parce qu'il n'y a qu'un autre scanf qui pose le meme probleme... Je comprends vraiment pas je me demande si c'est pas lié à la mémoire partagée ou aux sémaphores...
0