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 :

files de messages


Sujet :

Linux

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 17
    Points : 12
    Points
    12
    Par défaut files de messages
    Sos j’ai besoin d’aide en urgence
    Voila j’ai 5 processus fils et un père qui doivent communiquer en utilisant les fils de message
    1.Les fils envoi des messages au père et ce dernier les récupèrent
    2.Le père envoi des raiponces à ces fils
    Le problème est que je n’est jamais rencontré ces files de messages
    Si quelqu’un pourrai me donner la structure de données ainsi que les procédures nécessaire au fonctionnement (envoi et réception dans les deux cas) je serai vraiment reconnaissant
    Merci d’avance

  2. #2
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Non mais tu veux pas en plus qu'on te la tienne pendant que tu pisses aussi ?
    Faut quand-même faire aussi des efforts par toi-même. Surtout que si t'avais eu la politesse de regarder le lien proposé par Nicolas, tu verrais qu'il n'y a que 31 pages à lire (et la partie msq ne fait que 4 ou 5 pages !!!)
    Il n'y a pas de secret. Pour apprendre une technologie faut commencer par l'apprendre...
    j’ai pas demandé un psychologue et
    Il y’a exactement 6 page concernant les msq dans le doc

    Mais voila ce que j’appelle moi un résumé


    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
    Guillaume Bénétrix
    13/07/2004, 12h49
    Bonjour Madmac,
     
    Sous linux, il existe plusieurs techniques pour faire communiquer des processus entre eux. Les tubes, les FIFO et les IPC (Inter Communication Process). Comme j'ai pas trouvé en recherchant, voici un petit résumé sur ces techniques. A noter que je n'ai jamais programmé avec les tubes ou les FIFO, par contre les ipc, un peu.
     
    Les TUBES. Un tube est un flux de données à sens uniques entre des processus : toutes données écrites par un processus vers le tube sont acheminées par le noyau vers un autre processus, qui peut ainsi les lire. Les commandes shell (dans le terminal) |, > et < permettent cet acheminement. De même que les commandes systèmes (dans un programme C, C++,...) pipe(), read(), write() et close(). Les tubes sont à sens unique, il en faudra deux pour relier deux processus...
     
    Les FIFO. Depuis la sortie de System V Release 3, les FIFO sont implémentés en tant qu'objets fullduplex (bidirectionnels). Les fichiers FIFO comportent un inode de disque (et donc un nom de fichier accessible par le programme), mais n'utilisent pas de blocs de données. Les données sont stockées dans des tampons du noyau, ce qui est plus performant que d'utiliser des fichiers temporaires.... Un processus créer un FIFO en émettant l'appel système mknod() (qui peut servir à créer presque n'importe quel type fichier, sauf répertoires et sockets). Toutefois mkfifo() existe depuis System V Release 4. Les appels systèmes open(), read(), write() et close() peuvent accèder au FIFO une fois qu'il est créé.
     
    Les IPC : ces techniques permettent à des processus de partager de la mémoire partagée, de se synchroniser grâce à des sémaphores et de s'échanger des messages. Voici comment utiliser la mémoire partagée :
     
     
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/shm.h>
    int shmget(key_t key, int size, int shmflg);
    char *shmat(int shmid, car *shmadrr, int shmflg);
    int shmdt(chmadrr);
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
     
     
    shmget() donne l'identifiant du segment ayant la clef key (Pour constituer une clef, utiliser key_t ftok(char *pathname, char project)). Un nouveau segment de taille size est crée si key est IPC_PRIVATE, ou bien si les indicateurs de shmflg conntiennent IPC_CREAT. Combinées, les options IPC_EXCL | IPC_CRET indiquent que le segment ne doit pas exister auparavant. les bits de poids faible de shmflg indiquent les droits d'accès.
     
    shmat() attache le segment shmid en mémoire, avec les droits spécifiées dans shmflag (SHM_R, SHM_W, SHM_RDONLY). shmadrr précise où ce segment doit être situé dans l'espace mémoire (la valeur NULL demande un emplacement automatique). shmat() renvoie l'adresse où le segment a été placé.
     
    shmdt() sert à détacher le segmentsi on ne l'utilise plus.
     
    shmctl() permet de paramétrer ou de supprimer un segment partagé.
     
     
    // extraits choisis d'un simulateur d'ordonnanceurs
    int id, err;
    struct bcp * b;
    // Création du segment de mémoire partagée
    id = shmget( ftok( ".", '@'), sizeof( struct bcp )+10000, IPC_CREAT | IPC_EXCL | 0777 );
    if ( id < 0 )
    {
    printf("erreur shmget().\n");
    exit( -1 );
    }
    // Attribution de la mémoire partagée à la structure de données.
    b = (struct bcp *)shmat( id, 0, SHM_W );
    if ( b == NULL )
    {
    printf("erreur, shmat() == null.");
    exit( -1 );
    }
    // Détachement du segment de la structure.
    err = shmctl( bcp->id, IPC_RMID, NULL );
    if (err==-1)
    err = shmdt(bcp);
    printf("kill bcp err = %d.\n", err );
     
     
    La commande ipcs affiche des informations sur les segments/sémaphores/messages qui existent ; la commande ipcrm les supprime.
     
     
    [bnet@localhost bnet]$ ipcs
     
    ------ Segment de mémoire partagé --------
    clé shmid propriétaire perms octets nattch états
    0x00000000 32768 bnet 600 393216 2 dest
     
    ------ Tableaux de sémaphores --------
    clé semid propriétaire perms nsems
     
    ------ Queues de messages --------
    clé msqid propriétaire perms octets-utilisés messages
     
     
    Synchroniser des processus :
     
     
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/sem.h>
    int semget(key_t key, int nsems, int semflg);
    int semop(int semid, struct sembuf *sops, unsigned nsops);
    int semctl(int semid, int semnum, int cmd, union semun arg);
     
     
    La fonction semget() demande à travailler sur le sémaphore généralisé identifié par la clef key (cf. ci-dessus), et qui contient nsems sémaphores individuels. Un nouveau sémaphore est créé, avec les droits données par les 9 bits de poids faible de semflg, si key est IPC_PRIVATE, ou si semflg contient IPC_CREAT.
    La fonction semop() agit sur le sémaphore semid en appliquant simultanément à plusieurs sémaphores individuels les actions décrites dans les nsops premiers éléments du tableau sops.
     
     
    struct sembuf {
    ...
    short sem_num;
    short sem_op;
    short sem_flg;
    }
     
     
    sem_num est le numéro du sémaphore individuel sur lequel porte l'opération
    sem_op est un entier destiné (sauf s'il est nul) à être ajouté à la valeur courante semval du sémaphore. L'opération se bloque si sem_op + semval < 0. Cas particulier : si sem_op est 0, l'opération est bloquée tant que semval est non nul. Rq : les valeurs des sémaphores ne sont mises à jour que lorsqu'aucun d'eux n'est bloqué.
    La fonction semctl permet de réaliser diverses opérations sur les sémaphores, selon la commande demandée. En particulier, on peut fixer le n-ième sémaphore à la valeur val en faisant semctl(sem, n, SETVAL, val);
     
     
     
    #include <unistd.h>
    #include <sys/time.h>
    #include <sys/sem.h>
    #include <signal.h>
    #include <errno.h>
    #include <stdio.h>
     
    // Opération V ( +1 ) sur le 1er sémaphore de l'ensemble d'id sem.
    void V( int sem )
    {
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = 1;
    buf.sem_flg = 0;
    // printf("< V(%d) dans pid %d . \n", sem, getpid() );
    semop( sem, &buf, 1 );
    // printf("V(%d) dans pid %d. > \n", sem, getpid() );
    }
     
    // Opération P ( -1 ) sur le 1er sémaphore de l'ensemble d'id sem.
    void P( int sem )
    {
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = -1;
    buf.sem_flg = 0;
    // printf("< P(%d) dans pid %d . \n", sem, getpid() );
    semop( sem, &buf, 1 );
    // printf("P(%d) dans pid %d. > \n", sem, getpid() );
    }
     
    int new_semaphore( char id )
    {
    int _id, err;
    // printf("semaphore %d en création.\n", id );
    _id = semget( ftok( ".", id ), 1, IPC_CREAT | IPC_EXCL | 0777 );
    if ( _id == -1 )
    {
    printf("semget id : %c.\n", id );
    perror( "semget()" );
    exit( -1 );
    return -1;
    }
    err = semctl( _id, 0, SETVAL, 1 );
    if ( err == -1 )
    {
    perror( "semclt(SETVAL)" );
    exit( -1 );
    return -1;
    }
    // printf("semaphore %d crée ->%d \n", id, _id );
    return _id;
    }
     
    // détruit l'ensemble de sémaphores identifié par sema.
    void kill_semaphore( int sema )
    {
    // printf("kill semaphore %d.\n", sema );
    semctl( sema, 0, IPC_RMID, NULL );
    }
     
     
    Files de messages : ce mécanismes permet l'échange de messages par des processus. Chaque message possède un corps de longueur variable, et un type (entier strictement positif) qui peut servir à préciser la nature des informations contenues dans le corps. Au moment de la réception on peut choisir de sélectionner les messages d'un type donné.
     
     
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    int msgget(key_t key, int msgflg);
    int msgsnd(int msqid, struct *msgp, int msgflg);
    int msgrcv(int msqid, struct *msgp, int msgsz, int msgtyp, int msgflg);
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
     
     
    msgget() demande l'accès à (ou la création de) la file de message avec la clef key et retourne la valeur de l'identificateur de file.
    msgsnd() envoie un message dans la file msqid. Le corps de ce message contient msgsz octets. Il est placé, précédé par le type, dans le tampon pointé par msgp.
    Ce tampon est de la forme :
     
     
    struct msgbuf {
    long mtype;
    char mtext[..];
    }
     
     
    msgrcv() lit dans la file un message d'un type donné (si type>0) ou indifférent (si type==0), et le place dans le tampon pointé par msgp. La taille du corps ne pourra excéder msgsz octets, sinon il sera tronqué. Renvoie la taille du corps du message. Là par contre, pas d'exemple.
     
    En espérant que tu y trouvera ton bonheur, je te souhaite bon courage.
     
    ++

    Tous ce que je demande c’est un exemple exhaustif qui illustre ce qui vient d’être dit sur les msq

  3. #3
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Bonjours
    dans le cas ou j’ai plusieurs processus qui envoi des msg dans cette file
    et un qui les récupère dois je assurer l’exclusion mutuelle à cette fille
    (problème de producteur consommateur)
    ou la synchronisation est assuré par la structure des files des messages
    merci d’avance

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 043
    Points
    31 043
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par spark Voir le message
    Bonjours
    dans le cas ou j’ai plusieurs processus qui envoi des msg dans cette file
    et un qui les récupère dois je assurer l’exclusion mutuelle à cette fille
    (problème de producteur consommateur)
    ou la synchronisation est assuré par la structure des files des messages
    merci d’avance
    La synchronisation est assurée par la file elle-même car lorsqu'un message est récupéré, il est automatiquement supprimé de la file

    Bon, sinon t'as raison, il manque quand-même des exemples donc je te file les miens. Ils ont été écrits pour Unix donc sur Linux il risque d'y avoir quelques différences mais je pense que tu devrais arriver à t'en sortir

    Programme pour créer une file de messages
    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
    #include <sys/types.h>						/* Types prédéfinis "c"           */
    #include <sys/mode.h>						/* Modes et droits fichiers       */
    #include <sys/ipc.h>						/* Internal Process Comm.         */
    #include <sys/msg.h>						/* Boite aux lettres I.P.C.       */
    #include <stdio.h>							/* I/O fichiers classiques        */
    #include <errno.h>							/* Erreurs système                */
     
    extern const char* const sys_errlist[];		/* Liste messages erreurs         */
     
    main(
    	int argc, 								/* Nbre arguments                 */
    	char *argv[])							/* Ptr arguments                  */
    {
    	/* Déclaration des variables */
    	int msg_id;								/* Identifiant de la boite        */
    	key_t msg_key;							/* Clef de la boite               */
     
    	/* Verification au moins un argument */
    	if (argc <= 1)
    	{
    		fprintf(stderr, "Usage: %s clef\n", argv[0]);
    		exit(errno);
    	}
     
    	/* Conversion argument 1 (hexa) en nombre */
    	msg_key=strtoul(argv[1], NULL, 16);
     
    	/* Creation de la boite aux lettres */
    	if ((msg_id=msgget(msg_key, IPC_CREAT | IPC_EXCL | 0666)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgget(0x%08x) - %s\n", __LINE__, msg_key, sys_errlist[errno]);
    		exit(errno);
    	}
     
    	printf("Boite créée (id=%d)\n", msg_id); 
    }
    Tu le lances en lui passant en paramètre la clef de la file

    Programme 2 pour déposer un message dans la file
    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
    #include <sys/types.h>						/* Types prédéfinis "c"           */
    #include <sys/mode.h>						/* Modes et droits fichiers       */
    #include <sys/ipc.h>						/* Internal Process Comm.         */
    #include <sys/msg.h>						/* Boite aux lettres I.P.C.       */
    #include <stdio.h>							/* I/O fichiers classiques        */
    #include <errno.h>							/* Erreurs système                */
     
    extern const char* const sys_errlist[];		/* Liste messages erreurs         */
     
    #define SZ_MESSAGE			(255)			/* Taille max. message            */
     
    typedef struct {
    	int no;									/* No d'ordre                     */
    	char txt[SZ_MESSAGE]; 					/* Texte du message               */
    }t_corps;		 							/* Type "corps de message"        */
     
    typedef struct {
    	mtyp_t mtype;							/* Type de message                */
    	t_corps mcorps; 						/* Corps du message               */
    }t_msgbuf;		 							/* Type "message" au format "ipc" */
     
    /* Fonction principale */
    main(
    	int argc, 								/* Nbre arguments                 */
    	char *argv[])							/* Ptr arguments                  */
    {
    	/* Déclaration des variables */
    	int msg_id;								/* Identifiant de la boite        */
    	int status;								/* Status de retour fonction      */
    	int i;									/* Indice de boucle               */
    	key_t msg_key;							/* Clef de la boite               */
    	t_msgbuf msg_buf;						/* Message à envoyer              */
     
    	/* Vérification au moins deux arguments */
    	if (argc <= 2)
    	{
    		fprintf(stderr, "Usage: %s clef type [mess1 ...]\n", argv[0]);
    		exit(errno);
    	}
     
    	/* Conversion argument 1 (hexa) en nombre */
    	msg_key=strtoul(argv[1], NULL, 16);
     
    	/* Récuperation argument 2 pour type */
    	msg_buf.mtype=atol(argv[2]);
    	if (msg_buf.mtype == 0)
    		msg_buf.mtype=1;					/* Le type ne doit pas être à 0   */
     
    	/* Creation/Ouverture de la boite */
    	if ((msg_id=msgget(msg_key, IPC_CREAT|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgget(0x%08x) - %s\n", __LINE__, msg_key, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Boite aux lettres 0x%x ouverte - valeur %d\n", msg_key, msg_id);
     
    	/* Boucle sur le nombre d'arguments */
    	for (i=3; i < argc; i++)
    	{
    		/* Le n° du message est son n° d'ordre dans la liste des arguments */
    		msg_buf.mcorps.no=i - 2;
     
    		/* Le corps du message est l'argument "i" */
    		strcpy(msg_buf.mcorps.txt, argv[i]);
     
    		/* Envoi du message */
    		if ((status=msgsnd(msg_id, &msg_buf, sizeof(t_corps), IPC_NOWAIT)) == (-1))
    		{
    			fprintf(stderr, "ligne %u - msgsnd(%d) - %s\n", __LINE__, msg_id, sys_errlist[errno]);
    			continue;
    		}
    		printf("\tmessage(type=%d) '%s'... envoyé - status %d\n", msg_buf.mtype, msg_buf.mcorps.txt, status);
    	}
    }
    Tu le lances en lui passant en paramètre la clef de la file, le type du message (un chiffre différent de 0) et ensuite les messages à déposer (de simples mots)

    Programme 3 - Pour récupérer les messages d'une file
    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
    #include <sys/types.h>						/* Types prédéfinis "c"           */
    #include <sys/ipc.h>						/* Internal Process Comm.         */
    #include <sys/msg.h>						/* Boite aux lettres I.P.C.       */
    #include <stdio.h>							/* I/O fichiers classiques        */
    #include <errno.h>							/* Erreurs système                */
     
    extern const char* const sys_errlist[];		/* Liste messages erreurs         */
     
    #define SZ_MESSAGE			(255)			/* Taille max. message            */
     
    typedef struct {
    	int no;									/* No d'ordre                     */
    	char txt[SZ_MESSAGE]; 					/* Texte du message               */
    }t_corps;		 							/* Type "corps du message"        */
     
    typedef struct {
    	mtyp_t mtype;							/* Type de message                */
    	t_corps mcorps; 						/* Corps du message               */
    }t_msgbuf;		 							/* Type "message" au format "ipc" */
     
    /* Fonction principale */
    main(
    	int argc, 								/* Nbre arguments                 */
    	char *argv[])							/* Ptr arguments                  */
    {
    	/* Déclaration des variables */
    	unsigned short nb_msg;					/* Nombre de messages présents    */
    	int msg_id;								/* Identifiant de la boite        */
    	int status;								/* Status de retour fonction      */
    	mtyp_t msg_type;						/* Type message demandé           */
    	key_t msg_key;							/* Clef de la boite               */
    	t_msgbuf msg_buf;						/* Message à récupérer            */
    	struct msqid_ds info; 					/* Information boite              */
     
    	/* Vérification au moins un argument */
    	if (argc <= 1)
    	{
    		fprintf(stderr, "Usage: %s clef/id [type]\n", argv[0]);
    		exit(errno);
    	}
     
    	/* Conversion argument 1 (hexa) en nombre */
    	msg_key=strtoul(argv[1], NULL, 16);
     
    	/* Récupération argument 2 (si existant) pour type */
    	msg_type=(argc > 2) ?atol(argv[2]) :0;
     
    	/* Ouverture de la boite si clef valide */
    	if ((msg_id=msgget(msg_key, IPC_ALLOC)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgget(0x%08x) - %s\n", __LINE__, msg_key, sys_errlist[errno]);
    		msg_id=strtoul(argv[1], NULL, 10);
    		printf("Clef 0x%08x invalide => Utilisation identifiant %d\n", msg_key, msg_id);
    	}
    	printf("Boite aux lettres 0x%x ouverte - valeur %d\n", msg_key, msg_id);
     
    	/* Récuperation info boite */
    	if (msgctl(msg_id, IPC_STAT, &info) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgctl(%d) - %s\n", __LINE__, msg_id, sys_errlist[errno]);
    		exit(errno);
    	}
    	printf("Boite contient %hu messages (id=%d)\n", info.msg_qnum, msg_id); 
     
    	/* Boucle sur le nombre de messages */
    	for (nb_msg=info.msg_qnum; nb_msg > 0; nb_msg--)
    	{
    		/* Récupération du message */
    		status=msgrcv(msg_id, &msg_buf, sizeof(t_corps), msg_type, IPC_NOWAIT|MSG_NOERROR);
     
    		/* Si récupération impossible mais pas par manque de place */
    		if (status == (-1))
    		{
    			/* Si erreur n'est pas "plus de message" */
    			if (errno != ENOMSG)
    			{
    				fprintf(stderr, "ligne %u - msgrcv() - %s\n", __LINE__, sys_errlist[errno]);
    				exit(errno);
    			}
     
    			/* On sort de la boucle */
    			break;
    		}
     
    		/* Affichage chaine */
    		printf("\tmessage(type=%d): '%d %s' - status %d\n", msg_buf.mtype, msg_buf.mcorps.no, msg_buf.mcorps.txt, status);
    	}
     
    	/* Fin du programme */
    	printf("Fin des messages de type %d (0x%x)\n", msg_type, msg_key);
    }
    Tu le lances en lui passant en paramètre la clef de la file et le type des messages que tu veux récupérer mais ce paramètre est facultatif (=> si pas présent le programme récupère tous les messages)

    Programme 4 - Affiche les informations d'une file de messages
    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
    #include <sys/types.h>						/* Types prédéfinis "c"           */
    #include <sys/mode.h>						/* Modes et droits fichiers       */
    #include <sys/ipc.h>						/* Internal Process Comm.         */
    #include <sys/msg.h>						/* Boite aux lettres I.P.C.       */
    #include <stdio.h>							/* I/O fichiers classiques        */
    #include <pwd.h>							/* Info uid                       */
    #include <grp.h>							/* Info gid                       */
    #include <time.h>							/* Fonctions dates machines       */
    #include <errno.h>							/* Erreurs système                */
     
    static char *name_uid(uid_t);				/* Correspondance uid/nom         */
    static char *name_gid(gid_t);				/* Correspondance gid/nom         */
     
    extern const char* const sys_errlist[];		/* Liste messages erreurs         */
     
    /* Fonction principale */
    main(
    	int argc, 								/* Nbre arguments                 */
    	char *argv[])							/* Ptr arguments                  */
    {
    	/* Déclaration des variables */
    	int msg_id;								/* Identifiant de la boite        */
    	key_t msg_key;							/* Clef de la boite               */
    	struct msqid_ds info; 					/* Information boite              */
     
    	/* Vérification au moins un argument */
    	if (argc <= 1)
    	{
    		fprintf(stderr, "Usage: %s clef/id\n", argv[0]);
    		exit(errno);
    	}
     
    	/* Conversion argument 1 (hexa) en nombre */
    	msg_key=strtoul(argv[1], NULL, 16);
     
    	/* Ouverture de la boite si clef valide */
    	if ((msg_id=msgget(msg_key, IPC_ALLOC)) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgget(0x%08x) - %s\n", __LINE__, msg_key, sys_errlist[errno]);
    		msg_id=strtoul(argv[1], NULL, 10);
    		printf("Clef 0x%08x invalide => Utilisation identifiant %d\n", msg_key, msg_id);
    	}
     
    	/* Récuperation info boite */
    	if (msgctl(msg_id, IPC_STAT, &info) == (-1))
    	{
    		fprintf(stderr, "ligne %u - msgctl(%d) - %s\n", __LINE__, msg_id, sys_errlist[errno]);
    		exit(errno);
    	}
     
    	/* Affichage des champs de la structure IPC */
    	printf("Informations IPC (id=%d)\n", msg_id); 
    	printf("\tClef: %lu - 0x%x\n", info.msg_perm.key, info.msg_perm.key);
    	printf("\tPropriétaire: %d (%s)\n", info.msg_perm.uid, name_uid(info.msg_perm.uid));
    	printf("\tGroupe: %d (%s)\n", info.msg_perm.gid, name_gid(info.msg_perm.gid));
    	printf("\tCréateur: %d (%s)\n", info.msg_perm.cuid, name_uid(info.msg_perm.cuid));
    	printf("\tGroupe créateur: %d (%s)\n", info.msg_perm.cgid, name_gid(info.msg_perm.cgid));
    	fputs("\tMode: ", stdout);
    	fputc(((info.msg_perm.mode & S_IRUSR) == S_IRUSR) ?'r' :'-', stdout);
    	fputc(((info.msg_perm.mode & S_IWUSR) == S_IWUSR) ?'w' :'-', stdout);
    	fputc('-', stdout);
    	fputc(((info.msg_perm.mode & S_IRGRP) == S_IRGRP) ?'r' :'-', stdout);
    	fputc(((info.msg_perm.mode & S_IWGRP) == S_IWGRP) ?'w' :'-', stdout);
    	fputc('-', stdout);
    	fputc(((info.msg_perm.mode & S_IROTH) == S_IROTH) ?'r' :'-', stdout);
    	fputc(((info.msg_perm.mode & S_IWOTH) == S_IWOTH) ?'w' :'-', stdout);
    	fputc('-', stdout);
    	printf(" (%03o)\n", info.msg_perm.mode & 0777);
    	printf("\tSequence: %hu\n", info.msg_perm.seq);
     
    	/* Affichage des champs de la structure message */
    	printf("\nInformations boite (id=%d)\n", msg_id); 
    	printf("\tNb octets: %hu\n", info.msg_cbytes);
    	printf("\tNb messages: %hu\n", info.msg_qnum);
    	printf("\tNb octets max: %hu\n", info.msg_qbytes);
    	printf("\tPid dernier msgsnd(): %d\n", info.msg_lspid);
    	printf("\tPid dernier msgrcv(): %d\n", info.msg_lrpid);
    	printf("\tHeure dernier msgsnd(): %s", info.msg_stime ?ctime(&info.msg_stime) :"Néant\n");
    	printf("\tHeure dernier msgrcv(): %s", info.msg_rtime ?ctime(&info.msg_rtime) :"Néant\n");
    	printf("\tHeure dernier msgctl(): %s", info.msg_ctime ?ctime(&info.msg_ctime) :"Néant\n");
    }
     
    /* Fonction renvoyant un pointeur sur un nom correspondant à un "uid" */
    static char *name_uid(
    	uid_t uid)								/* uid demandé                    */
    {
    	/* Déclaration des variables */
    	struct passwd *id;						/* Info. uid                      */
     
    	/* Programmation */
    	id=getpwuid(uid);
    	return(id ?id->pw_name :"Inconnu");;
    }
     
    /* Fonction renvoyant un pointeur sur un nom correspondant à un "gid" */
    static char *name_gid(
    	gid_t gid)								/* gid demandé                    */
    {
    	/* Déclaration des variables */
    	struct group *id;						/* Info. gid                      */
     
    	/* Programmation */
    	id=getgrgid(gid);
    	return(id ?id->gr_name :"Inconnu");;
    }
    Tu le lances en lui passant en paramètre la clef de la file

  5. #5
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Je préfère plutôt ton coté informaticien Merci bien je me met au travaille

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/05/2006, 15h41
  2. [Debutant]Probleme file de message
    Par Treuze dans le forum C
    Réponses: 11
    Dernier message: 15/05/2006, 21h46
  3. Créer plusieures file de message différentes
    Par progamer54 dans le forum Linux
    Réponses: 6
    Dernier message: 06/04/2006, 15h36
  4. Réponses: 8
    Dernier message: 09/02/2006, 18h51
  5. IPC : Files de messages et accès exclusif
    Par thomasvst dans le forum C
    Réponses: 2
    Dernier message: 07/12/2005, 09h47

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