/******************************************************************************* ** ** Communication par files de messages. ** ----------------------------------- ** Ce programme se compose de trois processus et d'une file de messages. Le ** processus père est chargé de lire les caractères en provenance de l'entrée ** standard, d'envoyer les chiffres au premier fils (en utilisant un message ** de type 1) et les lettres au second (en utilisant un message de type 3). ** Une fois la fin de fichier atteinte, les fils renvoient leurs résultats ** au père (en utilisant respectivement des messages de type 2 et 4). Le père ** affiche ensuite les résultats. ** ** PS : Ce fichier est à visualiser en avec des tabulations de 4 caractères. ** ** © 2002, Éric Renault pour l'Institut National des Télécommunications. ** © 2013, François Trahay. ** *******************************************************************************/ # include # include # include # include # include # include #define MSG_DC 0 /* Distributeur -> Chiffre */ #define MSG_CD 1 /* Chiffre -> Distributeur */ #define MSG_DL 2 /* Distributeur -> Lettre */ #define MSG_LD 3 /* Lettre -> Distributeur */ #define MSG_NOMBRE 4 struct message { int valeur ; } ; /* ** Envoi d'un entier. */ void envoi_entier ( mqd_t msg_queue, int entier ) { int retour ; struct message message = { entier } ; retour = mq_send(msg_queue, (const char*)&message, sizeof(int), 0); assert ( retour == 0 ) ; } /* ** Réception d'un entier. */ int recoit_entier ( mqd_t msg_queue ) { struct message message ; int retour ; do { retour = mq_receive(msg_queue, (char*)&message, sizeof(int), NULL); assert ( retour == sizeof(int) ) ; } while ( retour == 0 ) ; return message . valeur ; } /* ** Somme des chiffres. */ void chiffre ( mqd_t lit, mqd_t ecrit ) { int car, somme = 0 ; /* Lecture des chiffres et somme. */ while ( ( car = recoit_entier ( lit ) ) != EOF ) somme += ( car - '0' ) ; fprintf(stderr, "fin de chiffre\n"); /* Renvoi du résultat. */ envoi_entier ( ecrit, somme ) ; } /* ** Fréquence des lettres. */ void lettre ( mqd_t lit, mqd_t ecrit ) { int car, frequence [ 'z' - 'a' + 1 ], i ; /* Initialisation. */ for ( i = 'a' ; i <= 'z' ; i ++ ) frequence [ i - 'a' ] = 0 ; /* Lecture des lettres et incrément des fréquences. */ while ( ( car = recoit_entier ( lit ) ) != EOF ) frequence [ tolower ( car ) - 'a' ] ++ ; /* Renvoi du résultat. */ for ( i = 'a' ; i <= 'z' ; i ++ ) envoi_entier ( ecrit, frequence [ i - 'a' ] ) ; } /* ** Distribution des caractères et affichage des résultats. */ void distributeur (mqd_t ecrit_c, mqd_t lit_c, mqd_t ecrit_l, mqd_t lit_l) { int car, i ; /* Distribution des caractères. */ do { car = getchar ( ) ; if ( isalpha ( car ) || ( car == EOF ) ) envoi_entier ( ecrit_l, car ) ; if ( isdigit ( car ) || ( car == EOF ) ) envoi_entier ( ecrit_c, car ) ; } while ( car != EOF ) ; /* Lecture et affichage de la somme. */ printf ( "Somme : %d", recoit_entier ( lit_c ) ) ; /* Lecture et affichage des fréquences. */ for ( i = 'a' ; i <= 'z' ; i ++ ) printf ( " ; %c : %d", i, recoit_entier ( lit_l ) ) ; printf ( "\n" ) ; } /* ** Mise en place de la file de messages et des processus. */ int main ( int argc, char * argv [ ] ) { mqd_t msg[MSG_NOMBRE]; char key[MSG_NOMBRE][80]; int retour; int i; sprintf(key[MSG_DC], "/CLE_MSG_QUEUE_DC"); sprintf(key[MSG_CD], "/CLE_MSG_QUEUE_CD"); sprintf(key[MSG_DL], "/CLE_MSG_QUEUE_DL"); sprintf(key[MSG_LD], "/CLE_MSG_QUEUE_LD"); struct mq_attr attr; attr.mq_flags = 0; attr.mq_maxmsg = 10; /* size of the message queue */ attr.mq_curmsgs = 0; attr.mq_msgsize = sizeof(struct message); /* size of one message */ /* Identification d'une file de message. */ for(i=0; i