Soyez le premier à donner votre avis sur cette source.
Snippet vu 14 305 fois - Téléchargée 20 fois
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <wait.h> #include <sys/ipc.h> // la bibliothèque des ipc : IPC_CREAT, IPC_EXCL, ... #include <sys/sem.h> // La bibliothèque des sémaphores... #include <sys/shm.h> // La bibliothèque de la mémoire partgeé... #include "ccrt.h" #define Max 10// le nombre maximal de cases dans le tampon... // les structures t_case et t_info typedef struct {// cette structure représente le contenue d'une case d'un tampon (contenant N cases)... int nb_rand; char ch_rand; } t_case; typedef struct { int i,j; // i: indice de la case où sera la production. j: indice de la case où sera la consommation. int plein;// nombre indiquant le nombre de cases pleines... } t_info; //les prototypes des fonctions.. void producteur(int); // le code du producteur void consommateur(int); //le code du consommateur void produire (t_case*); // la fonction qui simule la production void consommer (t_case); // la fonction qui simule la consommation void mettre(t_case); void prendre(t_case*); //fonctions de dessin... void tampon(int n); void affiche_prod(int np); void affiche_cons(int nc); void cacher_prod(int np); void cacher_cons(int nc); //les variables globales t_case* mem1;// le premier segement sera vu comme un tabelau de t_case t_info* mem2;// le deuxième segement sera vu comme un tabelau de t_case int nb_cases; // la taille du tampon int i_mutex; // mutex pour la variable i (de mem2) int j_mutex; // mutex pour la variable j (de mem2) int plein_mutex; // mutex pour la variable plein (de mem2) int file_prod; // sméphore qui représente la files des producteurs bloqués int file_cons; // sméphore qui représente la files des producteurs bloqués time_t t0; struct sembuf op_v= {0, +1, SEM_UNDO}; // l'opération V sur les sémaphores struct sembuf op_p= {0, -1, SEM_UNDO}; // l'opération P sur les sémaphores //La fonction principale... int main (){ pid_t f; int id_mem1, id_mem2; //identifiant des deux segments de mémoires partagées... const int taille1=0x6400, taille2=0x400; // les tailles des deux mémoires partagées... key_t cle;// une clé... int nb_p; // nombre de producteurs... int nb_c; // nombre de consommateurs... int num_p,num_c;// les numéros des producteurs et des consommateurs int i, st; ushort init_sem1[]={1}, init_sem0[]={0}; time(&t0); // la date du début de l'exécution du père... //génération de la clé... if ( (cle = ftok (".", 'a')) == -1){ perror ("ftok"); return -1; } //génération du segment de la première mémoire partagée... id_mem1 = shmget (cle, taille1, IPC_CREAT|IPC_EXCL|0666); if (id_mem1 == -1){ perror ("shmget - 1"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'b')) == -1){ perror ("ftok"); return -1; } //génération du segment de la deuxième mémoire partagée... id_mem2 = shmget (cle, taille2, IPC_CREAT|IPC_EXCL|0666); if (id_mem2 == -1){ perror ("shmget - 2"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'c')) == -1){ perror ("ftok"); return -1; } //génération du i_mutex... i_mutex = semget( cle, 1 ,IPC_CREAT|IPC_EXCL|0666); if (i_mutex == -1){ perror ("semget - 1"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'd')) == -1){ perror ("ftok"); return -1; } //génération du j_mutex... j_mutex = semget( cle, 1 ,IPC_CREAT|IPC_EXCL|0666); if (j_mutex == -1){ perror ("semget - 2"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'e')) == -1){ perror ("ftok"); return -1; } //génération du plein_mutex... plein_mutex = semget( cle, 1 ,IPC_CREAT|IPC_EXCL|0666); if (plein_mutex == -1){ perror ("semget - 3"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'f')) == -1){ perror ("ftok"); return -1; } //génération du file_prod... file_prod = semget( cle, 1 ,IPC_CREAT|IPC_EXCL|0666); if (file_prod == -1){ perror ("semget - 4"); return -1; } //génération de la clé... if ( (cle = ftok (".", 'g')) == -1){ perror ("ftok"); return -1; } //génération du file_cons... file_cons = semget( cle, 1 ,IPC_CREAT|IPC_EXCL|0666); if (file_cons == -1){ perror ("semget - 5"); return -1; } if (semctl (i_mutex, 0, SETALL, init_sem1)==-1){ perror ("semctl"); return -1; } if (semctl (j_mutex, 0, SETALL, init_sem1)==-1){ perror ("semctl"); return -1; } if (semctl (plein_mutex, 0, SETALL, init_sem1)==-1){ perror ("semctl"); return -1; } if (semctl (file_prod, 0, SETALL, init_sem0)==-1){ perror ("semctl"); return -1; } if (semctl (file_cons, 0, SETALL, init_sem0)==-1){ perror ("semctl"); return -1; } mem1 = shmat (id_mem1, 0, 0); // le premier segement sera vu comme un tabelau de t_case mem2 = shmat (id_mem2, 0, 0); // le deuxième segement sera vu comme une case t_info //initialisation des informations de la mémoire mem2 mem2->i=0; mem2->j=0; mem2->plein=0; //informations générales à introduire par l'utilisateur... printf ("nDonnez le nombre de cases du Tampon (entre 1 et %d) : ", Max); while (1){ scanf ("%d", &nb_cases);getchar(); if ((nb_cases<1)||(nb_cases>Max)) printf ("Erreur : vous deviez introduire un nombre entre 1 et %d : ", Max); else break; } printf ("nDonnez le nombre de producteurs (>=1) : "); while (1){ scanf ("%d", &nb_p);getchar(); if (nb_p<1) printf ("Erreur : vous deviez introduire un nombre >= 1"); else break; } printf ("nDonnez le nombre de consommateurs (>=1) : "); while (1){ scanf ("%d", &nb_c);getchar(); if (nb_c<1) printf ("Erreur : vous deviez introduire un nombre >= 1"); else break; } // Dessiner l'interface... ClrScr(); tampon(nb_cases); printf ("n"); // la création des producteurs num_p = 1; for (i=0; i<nb_p; i++){ srand (time(NULL));//assurer d'avoir des nombres aléatoires pour les différents producteurs f = fork(); if (f==-1){ perror ("fork- producteur"); return -1; } if (f==0){//la zone des producteurs.... producteur(num_p); return 0; }// fin de la zone des producteurs.... num_p++;// avoir le prochain numéro de producteur sleep(1);// attendre une seconde avant la prochaine création d'un fils } // la création des consommateurs num_c = 1; for (i=0; i<nb_c; i++){ srand (time(NULL));//assurer d'avoir des nombres aléatoires pour les différents consommateurs f = fork(); if (f==-1){ perror ("fork- producteur"); return -1; } if (f==0){//la zone des consommateurs.... consommateur(num_c); return 0; }// fin de la zone des consommateurs.... num_c++;// avoir le prochain numéro de producteur sleep(1);// attendre une seconde avant la prochaine création d'un fils } //attendre tous les fils... for (i=0; i<nb_p+nb_c; i++) wait(&st); // détachement des deux segments de mémoire partagée... shmdt (mem1); shmdt (mem2); if (shmctl (id_mem1, IPC_RMID, 0) == -1){ // suppression de la première mémoire partagée... perror ("shmctl - suppression 1"); return -1; } if (shmctl (id_mem2, IPC_RMID, 0) == -1){ // suppression de la première mémoire partagée... perror ("shmctl - suppression 2"); return -1; } if (semctl (i_mutex, 0, IPC_RMID, 0) == -1){ // la libération du sémaphore... perror ("semctl - 1"); return -1; } if (semctl (j_mutex, 0, IPC_RMID, 0) == -1){ // la libération du sémaphore... perror ("semctl - 1"); return -1; } if (semctl (plein_mutex, 0, IPC_RMID, 0) == -1){ // la libération du sémaphore... perror ("semctl - 1"); return -1; } if (semctl (file_prod, 0, IPC_RMID, 0) == -1){ // la libération du sémaphore... perror ("semctl - 1"); return -1; } if (semctl (file_cons, 0, IPC_RMID, 0) == -1){ // la libération du sémaphore... perror ("semctl - 1"); return -1; } TextColor (BLACK); TextBackground(WHITE); ClrScr(); GotoXY (1,1); return 0; }// fin de la fonction principale... //L'implémentation des fonctions void producteur(int np){//le porducteur... t_case c; time_t tc; time(&tc); affiche_prod(np); //srand (time(NULL)); while (1){ TextBackground (WHITE); GotoXY(15, 3+(np-1)*3); printf (" n"); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf ("t:%d | s'endormirn", tc-t0); sleep (rand()%3); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf (" n"); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf ("t:%d | produiren", tc-t0); produire(&c);// production d'un objet... sleep (rand()%2); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf (" n"); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf ("t:%d | Mettre dans le tamponn", tc-t0); mettre (c); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf ("t:%d | objet mis dans le tampon n", tc-t0); if ((rand()%5) == 0){ TextBackground (WHITE); TextColor (BLACK); GotoXY(15, 3+(np-1)*3); printf (" n"); break; } } time(&tc); cacher_prod(np); }// fin producteur... void consommateur(int nc){//le consommateur... t_case c; time_t tc; time(&tc); affiche_cons(nc); //srand (time(NULL)); while (1){ TextBackground (WHITE); TextColor (BLACK); GotoXY(70, 3+(nc-1)*3); printf (" n"); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(70, 3+(nc-1)*3); printf ("t:%d | s'endormirn", tc-t0); sleep (rand()%3); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(70, 3+(nc-1)*3); printf ("t:%d | prendre un objetn", tc-t0); prendre (&c); time(&tc); TextBackground (WHITE); TextColor (BLACK); GotoXY(70, 3+(nc-1)*3); printf ("t:%d | consommer un objetn", tc-t0); consommer(c);// cosnommer d'un objet... if ((rand()%5) == 0){ TextBackground (WHITE); TextColor (BLACK); GotoXY(70, 3+(nc-1)*3); printf (" "); break; } } time(&tc); cacher_cons(nc); }// fin cosommateur... void produire (t_case* c){//la production c->nb_rand = rand()%500; // un nombre aléatoire c->ch_rand = rand()%100+30; // un caractère aléatoire }// fin production void consommer (t_case c){//la consommation }// fin consommation void mettre(t_case c){// debut mettre semop(plein_mutex, &op_p, 1); if (mem2->plein == nb_cases){ semop(plein_mutex, &op_v, 1); semop(file_prod, &op_p, 1);// bloquage... semop(plein_mutex, &op_p, 1); } semop(plein_mutex, &op_v, 1); semop(i_mutex, &op_p, 1); mem1[mem2->i].nb_rand = c.nb_rand; mem1[mem2->i].ch_rand = c.ch_rand; mem2->i = (mem2->i+1) % nb_cases; semop(plein_mutex, &op_p, 1); mem2->plein++; semop(file_cons, &op_v, 1); semop(plein_mutex, &op_v, 1); GotoXY (52 ,3+mem2->i*3); TextColor (RED); printf (" n"); semop(i_mutex, &op_v, 1); }// fin mettre void prendre(t_case *c){// debut prendre semop(plein_mutex, &op_p, 1); if (mem2->plein == 0){ semop(plein_mutex, &op_v, 1); semop(file_cons, &op_p, 1);// bloquage... semop(plein_mutex, &op_p, 1); } semop(plein_mutex, &op_v, 1); semop(j_mutex, &op_p, 1); c->nb_rand = mem1[mem2->j].nb_rand; c->ch_rand = mem1[mem2->j].ch_rand; mem2->j = (mem2->j+1) % nb_cases; semop(plein_mutex, &op_p, 1); mem2->plein--; semop(file_prod, &op_v, 1); semop(plein_mutex, &op_v, 1); semop(j_mutex, &op_v, 1); }// fin prendre // les fonctions de dessins.. void tampon(int n){ //afficher le tampon... TextColor (BLUE); TextBackground(WHITE); int i; for (i=0; i<n; i++){ GotoXY(51 ,2+i*3); printf ("_____________"); GotoXY(50, 3+i*3); printf ("| |"); GotoXY(50, 4+i*3); printf ("| |"); GotoXY(50, 5+i*3); printf ("| |"); GotoXY(51, 5+i*3); printf ("_____________n"); } GotoXY (54, 3+i*3); TextColor (RED); printf ("TAMPON"); } void affiche_prod(int np){//afficher producteur GotoXY(5, 3+(np-1)*3); TextColor (WHITE); TextBackground(BLUE); printf (" Prod %d n", np); } void affiche_cons(int nc){//afficher consommateur GotoXY(100, 3+(nc-1)*3); TextColor (WHITE); TextBackground(RED); printf (" Cons %d n", nc); } void cacher_prod(int np){ GotoXY(5, 3+(np-1)*3); TextColor (WHITE); TextBackground(WHITE); printf (" n", np); } void cacher_cons(int nc){ GotoXY(100, 3+(nc-1)*3); TextColor (WHITE); TextBackground(WHITE); printf (" n", nc); }
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.