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 :

Programmation de FIFO


Sujet :

Linux

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut Programmation de FIFO
    Bonjour,

    je dois créer un programme en C sous linux pour ma seconde session d'un de mes cours.
    Je ne suis pas très alaise en programmation, de plus je n'ai pas été souvent a mes cours (problèmes personnel, et non pas du manque volontaire des cours).

    Je ne demande pas qu'on fasse l'exercice a ma place, juste de l'aide pour la compréhension, des tutos ou autres, qu'on me mette sur la voix :-)

    Voici l'énoncé :

    Réaliser un programme d'envoi/réception de messages codés (en ROT13, c-a-d décaler les lettres de 13 positions, de sorte que A->N, B-O, ...).

    L'envoi et la réception se fera dans une paire FIFOs comme sur la figure suivante :


    La figure montre deux instances du programme en cours d'exécution ; une a gauche et une a droite. Les deux FIFOs au centre permettent aux deux instances de communiquer.

    Le programme doit être constituer d'un seul fichier source (.c), mais composé de deux processus (fork).
    Le processus "envoi" est une boucle infinie qui lit les messages entrés par l'utilisateur, les encodent et les écris dans le FIFO d'envoi.
    Le processus "reception" récupère les messages dans le FIFO, les décodent, et les affichent a l'écran.

    Le noms des FIFOs ne peuvent pas être codés en dur dans le programme, vu que, comme l'illuste la figure, pour que les deux instances du programme communiquent le role de chaque FIFO est inversé pour chaque instance. Il faut passer le nom des FIFOs comme argument du programme.

    Voila, je vous avoue que pour moi c'est pas très clair dans la manière de codé, je ne sais vraiment pas par ou commencer... j'ai donc besoin d'aide.

    Pour rappel, c'est de l'aide que je demande et je ne veux bien entendu pas profiter et que la réponse me tombe tel quel (sauf si une âme charitable ^^ loool)

    Merci a tous

    PS: j'ai déja posté sur un autre forum ou on ma bien aidé pour le rot13 (partie facile) et on m'a conseillé de venir ici pour la suite que je n'arrive pas du tout a faire

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    J'ai juste une petite incompréhension par rapport à ton énoncé, peut tu clarifier ce qu'est le "nom d'une FIFO"? est ce que par la, tu entends un "tube nommé" (voir mkfifo()) ou bien s'agit il d'une spécification dont tu n'aurais pas parlé?
    Cordialement.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KenT2004 Voir le message
    Bonjour,

    je dois créer un programme en C sous linux pour ma seconde session d'un de mes cours.
    Je ne suis pas très alaise en programmation, de plus je n'ai pas été souvent a mes cours (problèmes personnel, et non pas du manque volontaire des cours).

    Je ne demande pas qu'on fasse l'exercice a ma place, juste de l'aide pour la compréhension, des tutos ou autres, qu'on me mette sur la voix :-)
    Voici un exemple de communication simple à travers un pipe mémoire

    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
    #include <sys/mode.h>				// Modes et droits fichiers
    #include <sys/wait.h>				// Attente fin de process
    #include <stdio.h>				// I/O fichiers classiques
    #include <signal.h>				// Signaux de communication
    #include <errno.h>				// Erreurs système               
     
    static void trt_sig(int);			// Détournement de signal         
     
    extern const char* const sys_errlist[];	// Liste messages erreurs
     
    #define SZ_STRING		(100)	// Taille message                 
     
    // Fonction principale 
    int main()
    {
    	// Déclaration des variables 
    	int pid;								// No process                     
    	int fin_fils;							// No fils fini                   
    	int status;								// Etat fin fils                  
    	int tube[2];							// Tableau extrémités tube        
     
    	char chaine[SZ_STRING];				// Chaine stockage message        
     
    	// Création tube memoire 
    	if (pipe(tube) != 0)
    	{
    		fprintf(stderr, "ligne %u - pipe() - %s\n", __LINE__, sys_errlist[errno]);
    		exit(errno);
    	}
     
    	// Création du process fils 
    	switch(pid=fork())
    	{
    		case (-1): // Erreur de fork 
    			fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]); 
    			exit(errno);
     
    		case 0: // Fils 
    			// Fermeture coté inutilisé 
    			close(tube[1]);
     
    			// Attente que le père ait commençé 
    			sleep(1);
     
    			// Boucle de lecture 
    			while (strcmp(chaine, "EOT\n") != 0)
    			{
    				// Lecture du tube 
    				read(tube[0], chaine, SZ_STRING);
    				printf("\tFils(%u) - J'ai reçu '%s'\n", getpid(), chaine);
     
    				// Signal au père qu'il peut continuer 
    				kill(getppid(), SIGALRM);
    			}
     
    			// Fermeture coté utilisé 
    			close(tube[0]);
     
    			// Arret du fils 
    			printf("\tFils(%d) - Je m'arrête\n", getpid());
    			exit(0);
     
    		default: // Père 
    			// Inhibition signal SIGALRM 
    			signal(SIGALRM, trt_sig);
     
    			// Fermeture coté inutilisé 
    			close(tube[0]);
     
    			printf("Je suis le père %u de mon fils %u\n", getpid(), pid);
     
    			// Boucle d'écriture 
    			while (strcmp(chaine, "EOT\n") != 0)
    			{
    				// Saisie et envoi de la chaine 
    				printf("Père(%u) - Entrez une chaine (EOT pour sortir):", getpid());
    				fgets(chaine, SZ_STRING, stdin);
    				write(tube[1], chaine, strlen(chaine) + 1);
     
    				// Attente que le fils ait traité ma chaine 
    				pause();
    			}
     
    			// Fermeture coté utilisé 
    			close(tube[1]);
     
    			// Attente mort de mon fils 
    			wait(&status);
    			printf("Mon fils %u vient de mourir - Mort(%u)\n", pid, WEXITSTATUS(status));
    	}
     
    	return 0;
    }
     
    // Fonction de détournement du signal reçu 
    static void trt_sig(
    	int sig)								// Signal reçu                    
    {
    	// Repositionnement du détournement du signal 
    	signal(sig, trt_sig);
    }
    Une fois que t'auras bien pigé le fonctionnement, t'auras aucun problème pour faire ton TP.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    c'est bien des tube nommée les FIFOs.

    Merci, je vais lire ca et tester :-)

  5. #5
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Sve@r Voir le message

    Ensuite voici un exemple de communication simple à travers un pipe mémoire

    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
    #include <sys/mode.h>				// Modes et droits fichiers
    #include <sys/wait.h>				// Attente fin de process
    #include <stdio.h>				// I/O fichiers classiques
    #include <signal.h>				// Signaux de communication
    #include <errno.h>				// Erreurs système               
     
    static void trt_sig(int);			// Détournement de signal         
     
    extern const char* const sys_errlist[];	// Liste messages erreurs
     
    #define SZ_STRING		(100)	// Taille message                 
     
    // Fonction principale 
    int main()
    {
    	// Déclaration des variables 
    	int pid;								// No process                     
    	int fin_fils;							// No fils fini                   
    	int status;								// Etat fin fils                  
    	int tube[2];							// Tableau extrémités tube        
     
    	char chaine[SZ_STRING];				// Chaine stockage message        
     
    	// Création tube memoire 
    	if (pipe(tube) != 0)
    	{
    		fprintf(stderr, "ligne %u - pipe() - %s\n", __LINE__, sys_errlist[errno]);
    		exit(errno);
    	}
     
    	// Création du process fils 
    	switch(pid=fork())
    	{
    		case (-1): // Erreur de fork 
    			fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]); 
    			exit(errno);
     
    		case 0: // Fils 
    			// Fermeture coté inutilisé 
    			close(tube[1]);
     
    			// Attente que le père ait commençé 
    			sleep(1);
     
    			// Boucle de lecture 
    			while (strcmp(chaine, "EOT\n") != 0)
    			{
    				// Lecture du tube 
    				read(tube[0], chaine, SZ_STRING);
    				printf("\tFils(%u) - J'ai reçu '%s'\n", getpid(), chaine);
     
    				// Signal au père qu'il peut continuer 
    				kill(getppid(), SIGALRM);
    			}
     
    			// Fermeture coté utilisé 
    			close(tube[0]);
     
    			// Arret du fils 
    			printf("\tFils(%d) - Je m'arrête\n", getpid());
    			exit(0);
     
    		default: // Père 
    			// Inhibition signal SIGALRM 
    			signal(SIGALRM, trt_sig);
     
    			// Fermeture coté inutilisé 
    			close(tube[0]);
     
    			printf("Je suis le père %u de mon fils %u\n", getpid(), pid);
     
    			// Boucle d'écriture 
    			while (strcmp(chaine, "EOT\n") != 0)
    			{
    				// Saisie et envoi de la chaine 
    				printf("Père(%u) - Entrez une chaine (EOT pour sortir):", getpid());
    				fgets(chaine, SZ_STRING, stdin);
    				write(tube[1], chaine, strlen(chaine) + 1);
     
    				// Attente que le fils ait traité ma chaine 
    				pause();
    			}
     
    			// Fermeture coté utilisé 
    			close(tube[1]);
     
    			// Attente mort de mon fils 
    			wait(&status);
    			printf("Mon fils %u vient de mourir - Mort(%u)\n", pid, WEXITSTATUS(status));
    	}
     
    	return 0;
    }
     
    // Fonction de détournement du signal reçu 
    static void trt_sig(
    	int sig)								// Signal reçu                    
    {
    	// Repositionnement du détournement du signal 
    	signal(sig, trt_sig);
    }
    ça ne te ressemble pas ce genre de code Frédéric!!!

    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/wait.h>    // Attente fin de process
    #include <stdio.h>    // I/O fichiers classiques
    #include <signal.h>    // Signaux de communication
    #include <errno.h>    // Erreurs système
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define SZ_STRING 100 // Taille message
     
    // Fonction de détournement du signal reçu
    static void trt_sig (int sig)// Signal reçu
    {
       // Repositionnement du détournement du signal
       signal(sig, trt_sig);
    }
     
    // Fonction principale
    int main (void)
    {
       int ret = 0;
       int tube[2];       // Tableau extrémités tube
     
       // Création tube memoire
       if (pipe (tube) != 0)
       {
          fprintf (stderr, "ligne %u - pipe() - %s\n", __LINE__, strerror (errno));
          ret = EXIT_FAILURE;
       }
       else
       {
          char chaine[SZ_STRING];    // Chaine stockage message
          pid_t pid = fork();
          // Création du process fils
          switch (pid)
          {
             case -1: // Erreur de fork
                fprintf (stderr, "ligne %u - fork() - %s\n", __LINE__,
                         strerror(errno));
                ret = EXIT_FAILURE;
     
             case 0: // Fils
                // Fermeture coté inutilisé
                close (tube[1]);
     
                // Attente que le père ait commençé
                sleep (1);
     
                // Boucle de lecture
                while (strcmp (chaine, "EOT\n") != 0)
                {
                   // Lecture du tube
                   read (tube[0], chaine, sizeof chaine);
                   printf ("\tFils(%ld) - J'ai reçu '%s'\n", (long)getpid (), 
                           chaine);
     
                   // Signal au père qu'il peut continuer
                   kill (getppid (), SIGALRM);
                }
     
                // Fermeture coté utilisé
                close (tube[0]);
     
                // Arret du fils
                printf ("\tFils(%ld) - Je m'arrête\n", (long)getpid ());
                break;
     
             default: // Père
             {
                int status;        // Etat fin fils
                // Inhibition signal SIGALRM
                signal (SIGALRM, trt_sig);
     
                // Fermeture coté inutilisé
                close (tube[0]);
     
                printf ("Je suis le père %ld de mon fils %ld\n", (long)getpid (),
                        (long)pid);
     
                // Boucle d'écriture
                while (strcmp (chaine, "EOT\n") != 0)
                {
                   // Saisie et envoi de la chaine
                   printf ("Père(%ld) - Entrez une chaine (EOT pour sortir):",
                           (long)getpid ());
                   fgets (chaine, SZ_STRING, stdin);
                   write (tube[1], chaine, strlen (chaine) + 1);
     
                   // Attente que le fils ait traité ma chaine
                   pause ();
                }
     
                // Fermeture coté utilisé
                close (tube[1]);
     
                // Attente mort de mon fils
                wait (&status);
                printf ("Mon fils %ld vient de mourir - Mort(%u)\n", (long)pid,
                        WEXITSTATUS (status));
             }
          }
       }
     
       return ret;
    }

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    ça ne te ressemble pas ce genre de code Frédéric!!!

    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/wait.h>    // Attente fin de process
    #include <stdio.h>    // I/O fichiers classiques
    #include <signal.h>    // Signaux de communication
    #include <errno.h>    // Erreurs système
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define SZ_STRING 100 // Taille message
     
    // Fonction de détournement du signal reçu
    static void trt_sig (int sig)// Signal reçu
    {
       // Repositionnement du détournement du signal
       signal(sig, trt_sig);
    }
     
    // Fonction principale
    int main (void)
    {
       int ret = 0;
       int tube[2];       // Tableau extrémités tube
     
       // Création tube memoire
       if (pipe (tube) != 0)
       {
          fprintf (stderr, "ligne %u - pipe() - %s\n", __LINE__, strerror (errno));
          ret = EXIT_FAILURE;
       }
       else
       {
          char chaine[SZ_STRING];    // Chaine stockage message
          pid_t pid = fork();
          // Création du process fils
          switch (pid)
          {
             case -1: // Erreur de fork
                fprintf (stderr, "ligne %u - fork() - %s\n", __LINE__,
                         strerror(errno));
                ret = EXIT_FAILURE;
     
             case 0: // Fils
                // Fermeture coté inutilisé
                close (tube[1]);
     
                // Attente que le père ait commençé
                sleep (1);
     
                // Boucle de lecture
                while (strcmp (chaine, "EOT\n") != 0)
                {
                   // Lecture du tube
                   read (tube[0], chaine, sizeof chaine);
                   printf ("\tFils(%ld) - J'ai reçu '%s'\n", (long)getpid (), 
                           chaine);
     
                   // Signal au père qu'il peut continuer
                   kill (getppid (), SIGALRM);
                }
     
                // Fermeture coté utilisé
                close (tube[0]);
     
                // Arret du fils
                printf ("\tFils(%ld) - Je m'arrête\n", (long)getpid ());
                break;
     
             default: // Père
             {
                int status;        // Etat fin fils
                // Inhibition signal SIGALRM
                signal (SIGALRM, trt_sig);
     
                // Fermeture coté inutilisé
                close (tube[0]);
     
                printf ("Je suis le père %ld de mon fils %ld\n", (long)getpid (),
                        (long)pid);
     
                // Boucle d'écriture
                while (strcmp (chaine, "EOT\n") != 0)
                {
                   // Saisie et envoi de la chaine
                   printf ("Père(%ld) - Entrez une chaine (EOT pour sortir):",
                           (long)getpid ());
                   fgets (chaine, SZ_STRING, stdin);
                   write (tube[1], chaine, strlen (chaine) + 1);
     
                   // Attente que le fils ait traité ma chaine
                   pause ();
                }
     
                // Fermeture coté utilisé
                close (tube[1]);
     
                // Attente mort de mon fils
                wait (&status);
                printf ("Mon fils %ld vient de mourir - Mort(%u)\n", (long)pid,
                        WEXITSTATUS (status));
             }
          }
       }
     
       return ret;
    }
    Sisi c'est bien le mien mais il s'agit d'un code vieux de 1999 qui tournait sur un vrai Unix (et non un Linux) que j'ai retrouvé. A l'époque j'utilisais sys_errlist[] car strerror() soit n'existait pas, soit je ne le connaissais pas. J'ai pas eu envie de le corriger (mais j'ai quand-même remplacé les /* ... */ d'origine par des // ...)
    Sinon je vois pas trop de différence. Bon tu préfères éviter les exit() multiples (mais ça c'est plus une habitude d'Emmanuel et non de la mienne) et tu améliores un peu les typages (pid_t au lieu des int) mais là aussi c'est de l'évolution plus ou moins récente
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    Bonjour,

    moi ce que j'ai besoin ce sont des tubes de communication, car les processus doivent communiquer entre deux (je dois ouvrir deux terminaux et envoyer de l'un a l'autre les données).

    Les codes que vous me montrez ne permettent pas de faire de la communication (je me trompe ?).

    Si vous avez qui traine dans un vieux Unix, des example de tubes de communication (tubes nommés il me semble que j'ai besoin ?) je suis preneur.

    merci

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KenT2004 Voir le message
    Bonjour,

    moi ce que j'ai besoin ce sont des tubes de communication, car les processus doivent communiquer entre deux (je dois ouvrir deux terminaux et envoyer de l'un a l'autre les données).
    Déjà t'as même pas lu ma doc (pourtant il n'y a que 24 pages et la partie tubes ne fait que 3 pages)

    Citation Envoyé par KenT2004 Voir le message
    Les codes que vous me montrez ne permettent pas de faire de la communication (je me trompe ?).
    Ben si. Il y a 2 processus et le père attend des données tapées au clavier qu'il envoie au fils (via un tube de communication). Le fils lit les données (du tube de communication) et les affiche à l'écran. Si ça c'est pas de la communication...

    Citation Envoyé par KenT2004 Voir le message
    Si vous avez qui traine dans un vieux Unix, des example de tubes de communication (tubes nommés il me semble que j'ai besoin ?)
    Ah ? Tu sembles quand-même avoir pris la peine de chercher un peu par toi-même. Effectivement si les processus ne sont pas liés père/fils tu ne peux passer que par un tube nommé.

    Tu veux un exemple ? Commences par ouvrir 2 terminaux et tapes dans chacun d'eux les commandes suivantes
    * t1:
    mknod /tmp/toto p
    date >/tmp/toto => là le curseur se bloque. Tu passes alors au t2

    * t2:
    cat /tmp/toto => là tu récupères la date issue du premier terminal et le curseur du premier terminal est débloqué

    Ensuite t'as plus qu'à refaire l'expérience avec deux programmes C (deux codes sources) qui donneront en final 2 processus

    p1:
    - créer le tube (mkfifo)
    - ouvrir le tube (open ou fopen)
    - écrire dans le tube (write ou fputs)
    - fermer le tube (close ou fclose)

    p2
    - ouvrir le tube (open ou fopen)
    - lire le tube (read ou fgets)
    - fermer le tube (close ou fclose)

    Un peu de gestion intelligente des données (boucle d'écriture/lecture qui stoppe par exemple sur une certaine séquence style "EOT" comme "End Of Text") et c'est fini. Le code source donné hier peut même être repris et à peine modifié pour correspondre à ce schéma. Tu lances le premier programme dans un premier terminal, le second programme dans un second terminal et tu as ta comm.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    Bien sur que si j'ai lu ta doc, elle m'a d'ailleurs bien aidé pour la compréhension théorique et pour décortiquer mon TP.
    j'ai essayé de lancer le code dans deux terminaux, mais les PID ne sont pas les même a ce moment la, les processus ne peuvent pas se lire entre eux ?
    Désolé si je parait largué, mais je suis largué ... j'ai du mal a visualiser.

    EDIT : je fais un test sur la communication et je te dis quoi (un "bête" programme)

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    Voila ce que j'ai réalisé (c'est tres basique), mais il n'écrit pas dans le fichier.

    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    int main()
    {
     
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
     
    	fifo = mkfifo(fifoName, 0600);
    	fich = fopen(fifoName, "w");
     
    	fifo = fputs("Salut", fich);
    	fclose(fich);
     
    	fich = fopen(fifoName, "r");
    	fgets(chaine, 256, fich);
    	printf("%s", chaine);
    	fclose(fich);
     
     
     
    }

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 67
    Par défaut
    Salut Kent, je regardais un peu l'énoncé de ton programme. Lorsqu'il parle d'une instance c'est l'exécution des 2 processus envoi/réception?

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    dans instance, il veut parler de deux terminaux donc la communication de l'un vers l'autre.
    Il faut de toute facon deux processus, un envoi et un réception.

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KenT2004 Voir le message
    j'ai essayé de lancer le code dans deux terminaux, mais les PID ne sont pas les même a ce moment la, les processus ne peuvent pas se lire entre eux ?
    Désolé si je parait largué, mais je suis largué ... j'ai du mal a visualiser.
    Eh oui, c'est la visualisation qui est la plus importante. Mon exemple donné hier était un exemple de communication entre 2 processus issus d'un seul programme. Le programme génère les deux processus (on les appelle alors père/fils car l'un est le fils de l'autre) et le processus 1 (le père) envoie des infos au p2 (le fils) mais l'ensemble reste confiné dans le programme. Si tu le lances deux fois ben les deux instances resteront indépendantes et ne parleront pas entre elles.

    En fait, faut bien distinguer deux types de pipes
    - les pipes mémoires => rapides mais ne peuvent être utilisés que par deux processus créés à partir d'une même racine. C'est normal quand on y réfléchit => il faut que les deux processus aient tous deux connaissance de la zone mémoire utilisée par le pipe donc il faut qu'ils soient créés par le même processus que celui qui crée le pipe mémoire
    - les pipes nommés => peuvent être utilisés par n'importe quels processus indépendants mais nécessitent un support sur le disque => le fichier pipe

    Citation Envoyé par KenT2004 Voir le message
    Voila ce que j'ai réalisé (c'est tres basique), mais il n'écrit pas dans le fichier.

    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    int main()
    {
     
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
     
    	fifo = mkfifo(fifoName, 0600);
    	fich = fopen(fifoName, "w");
     
    	fifo = fputs("Salut", fich);
    	fclose(fich);
     
    	fich = fopen(fifoName, "r");
    	fgets(chaine, 256, fich);
    	printf("%s", chaine);
    	fclose(fich);
     
     
     
    }
    Ben c'est déjà un début. Seul défaut => tu as voulu faire l'écriture et la lecture à suivre alors que l'écriture bloque ton processus vu qu'il n'y a pas encore de lecture (comme te l'a montré le petit TP à base de commandes shell) donc le programme bloque au fputs() et ne fait pas la suite.

    Sépare ce source en deux sources (l'un qui fait l'écriture et l'autre qui fait la lecture) puis lance le premier dans un terminal => il sera alors bloqué puisque tu écris sans lire) et lance ensuite le second dans un autre terminal => Tu obtiendras dans le second terminal ta chaine écrite par le premier programme et les deux terminaux seront débloqués. Et attention à la perte de variables (tu as écrit fifo=mkfifo() puis fifo=fputs() => cette dernière affectation est inutile...)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    Juste, j'avais pas pensé a ca !! Mais ca me pose un gros problème.

    Voici mes codes :

    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
     
    void rot13(char * str) { 
     
      static char const * const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM"
     
                                          "abcdefghijklmnopqrstuvwxyzabcdefghijklm";
     
      int i = 0;
     
     
     
        while( str[i] != 0 ) {
             char * found = strchr( letters, str[i] );
     
             if( found != NULL )
     
               str[i] = *(found + 13);
     
     
     
             i++;
     
       }
     
    }
     
    int main()
    {
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
    	char s[256];
     
    	printf("Tapez une phrase : ");
    	fgets(s, sizeof s, stdin);
    	rot13(s);
     
    	fifo = mkfifo(fifoName, 0600);
    	fich = fopen(fifoName, "w");
     
    	fputs(s, fich);
    	fclose(fich);
    }
    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    int main()
    {
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
     
    	fifo = mkfifo(fifoName, 0600);
     
    	fich = fopen(fifoName, "r");
    	fgets(chaine, 256, fich);
    	printf("%s", chaine);
    	fclose(fich);
     
    }
    Ca fonctionne très bien, seulement je dois tout faire en UN fichier.C (comment faire ? switch...case ?), de plus il faut renvoyer le décryptage vers le premier terminal :
    T1 cryptage (rot13) de la phrase tapé ===envois===> a T2 qui l'affiche la phrase crypté
    T2 décryptage (rot13) ===envois===> T1 qui affiche la phrase en claire

  15. #15
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KenT2004 Voir le message
    Juste, j'avais pas pensé a ca !! Mais ca me pose un gros problème.

    Voici mes codes :

    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
     
    void rot13(char * str) { 
     
      static char const * const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM"
     
                                          "abcdefghijklmnopqrstuvwxyzabcdefghijklm";
     
      int i = 0;
     
     
     
        while( str[i] != 0 ) {
             char * found = strchr( letters, str[i] );
     
             if( found != NULL )
     
               str[i] = *(found + 13);
     
     
     
             i++;
     
       }
     
    }
     
    int main()
    {
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
    	char s[256];
     
    	printf("Tapez une phrase : ");
    	fgets(s, sizeof s, stdin);
    	rot13(s);
     
    	fifo = mkfifo(fifoName, 0600);
    	fich = fopen(fifoName, "w");
     
    	fputs(s, fich);
    	fclose(fich);
    }
    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
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
     
    int main()
    {
    	char fifoName[]="/tmp/testfifo2";
    	char chaine[256] = "";
    	int fifo;
    	FILE *fich;
     
    	fifo = mkfifo(fifoName, 0600);
     
    	fich = fopen(fifoName, "r");
    	fgets(chaine, 256, fich);
    	printf("%s", chaine);
    	fclose(fich);
     
    }
    Ca fonctionne très bien, seulement je dois tout faire en UN fichier.C (comment faire ? switch...case ?), de plus il faut renvoyer le décryptage vers le premier terminal :
    T1 cryptage (rot13) de la phrase tapé ===envois===> a T2 qui l'affiche la phrase crypté
    T2 décryptage (rot13) ===envois===> T1 qui affiche la phrase en claire
    Concernant le passage de T1 à T2 puis T2 à T1 maintenant que tu sais envoyer des data à travers un pipe tu devrais avoir aucun problème pour ça. Dans ton schéma initial tuas dessiné 2 tubes donc tu peux très bien utiliser 2 pipes (un qui va de T1 vers T2 et un qui va de T2 vers T1).

    Maintenant concernant l'histoire d'un seul source là je suis étonné. Mais il peut y avoir plusieurs réponses
    1) soit tu interprètes à ta façon l'énoncé alors qu'on ne t'oblige absolument pas à n'avoir qu'un seul source => dans ce cas pas de pb

    2) soit il s'agit d'un source qui va générer plusieurs processus (à la façon de mon exemple initial) et chaque processus pourra gérer sa partie => dans ce cas tu peux rester avec les pipes nommés ou utiliser des pipes mémoires

    3) soit il est réellement demandé de n'avoir qu'un source qui fasse les 2 actions => dans ce cas tu programmes une fonction t1() qui fera l'action de T1, une fonction t2() qui fera l'action de T2 et un main() qui détecte lors du lancement si tu le lances en tant que T1 ou en tant que T2 et qui, selon le cas, appelle t1() ou t2() => tu peux utiliser un argument pour ça ou même tester avec le nom de l'exécutable argv[0] (comme cela était le cas à une époque avec les commandes chown et chgrp qui étaient un seul et unique exécutable mais si on appelait chown l'exécutable détectait ce nom et faisait l'action de chown et si on appelait chgrp il lançait l'action de chgrp)

    Maintenant
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    c'est exactement le point 2 que je dois faire (je n'ai pas tapé l'intégralité de l'énoncé).

    je fais quelques test et je te recontact si j'ai besoin d'aide.
    Merci beaucoup en tout cas

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 34
    Par défaut
    Voila, j'ai réussi a faire quelques choses qui se rapproche vraiment du travail demandé :

    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
    #include <sys/wait.h>   
    #include <stdio.h>    
    #include <signal.h>   
    #include <errno.h>    
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
     
    void rot13(char * str) { 
     
      static char const * const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLM"
     
                                          "abcdefghijklmnopqrstuvwxyzabcdefghijklm";
     
      int i = 0;
     
     
     
        while( str[i] != 0 ) {
             char * found = strchr( letters, str[i] );
     
             if( found != NULL )
     
               str[i] = *(found + 13);
     
             i++;
     
       }
     
    }
     
    static void trt_sig (int sig)
    {
       signal(sig, trt_sig);
    }
     
    int main (int argc, char *argv[])
    {
       int ret = 0;
       int tube[2];       
       char fifo1PATH[100]={0};
       char fifo2PATH[100]={0};
       char chaine[256] = "";
       int fifo1;
       int fifo2;
       FILE *fich01;
       FILE *fich02;
       char s[256];
     
       strcpy (fifo1PATH,argv[1]);  
       strcpy (fifo2PATH, argv[2]);
     
       pid_t pid = fork();
     
       switch (pid) {
             case -1: 
                fprintf (stderr, "ligne %u - fork() - %s\n", __LINE__,
                         strerror(errno));
                ret = EXIT_FAILURE;
     
             case 0: 
                close(fifo1);
                sleep (1);
     
                while (strcmp (chaine, "STOP\n") != 0) {
    		   fich01 = fopen(fifo2PATH, "r");
    	           fgets(chaine, 256, fich01);
    		    rot13(chaine);
    		    printf("%s", chaine);
    		    fclose(fich01);
                        kill (getppid (), SIGALRM);
                }
    	    printf("\tStop\n");	
                break;
     
             default: 
             {
                int status;        
                signal (SIGALRM, trt_sig);
     
                while (strcmp (chaine, "STOP\n") != 0) {
    		   fgets(s, sizeof s, stdin);
    		   rot13(s);
    		   fifo1 = mkfifo(fifo1PATH, 0600);
    		   fich01 = fopen(fifo1PATH, "w");
    		    fputs(s, fich01);
    		    fclose(fich01);		
                }
                wait (&status);
             }
       }
       return ret;
    }
    Il y a quelques bug, dans le style qu'il écrit parfois deux fois dans le terminal 2 ce que j'ai envoyé depuis le terminal 1 ... pq ? aucune idée, donc si quelqu'un voit, je suis preneur !!

    Autre problème, vu que c'est un programme de cryptage, parfois il écrit la ligne crypté alors qu'il devrait la décrypter. Je ne sais pas pq non plus.

    Pourrais-tu m'expliquez ces quelques lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    static void trt_sig (int sig)
    {
       signal(sig, trt_sig);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
             case -1: 
                fprintf (stderr, "ligne %u - fork() - %s\n", __LINE__,
                         strerror(errno));
                ret = EXIT_FAILURE;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                int status;        
                signal (SIGALRM, trt_sig);
    Merci et dis moi ce que tu en penses

  18. #18
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KenT2004 Voir le message
    c'est exactement le point 2 que je dois faire (je n'ai pas tapé l'intégralité de l'énoncé).
    Alors là je pige plus du tout car l'exemple que j'ai donné hier correspondait exactement au point 2 (à savoir une communication père/fils) et voici la réponse que t'as faite en retour

    Bonjour,

    moi ce que j'ai besoin ce sont des tubes de communication, car les processus doivent communiquer entre deux (je dois ouvrir deux terminaux et envoyer de l'un a l'autre les données).

    Les codes que vous me montrez ne permettent pas de faire de la communication (je me trompe ?).
    Si tu utilises 2 terminaux alors ce ne sont pas des père/fils mais deux programmes indépendants...

    Citation Envoyé par KenT2004 Voir le message
    Merci et dis moi ce que tu en penses
    Je pense que tu vas un peu dans tous les sens comme un chien fou alors qu'en te posant 2mn pour bien construire ton code tu pourrais gagner en clarté et en temps de développement

    Par exemple pourquoi ce close(fifo1) ??? Pourquoi dans rot13 tu fais un strchr(str[i]) alors que tu as déjà la position de cette lettre qui est "i" ? (tiens juste pour rire, essaye d'afficher au format "%lu" ou "%x" la valeur "str + i" et la variable "found")

    Autre chose => fabrique-toi les types dont t'as besoin. Par exemple il me semble que tu utilises pour un pipe
    - un nom de fichier
    - un pointeur FILE *
    Mais comme t'as deux pipes tu es obligé de dédoubler ces variables et tu dois en gérer 4.
    Pourquoi ne pas utiliser une structure ???
    typedef struct {
    char nom[100];
    FILE *pt;
    } t_pipe;

    Puis créer 2 variables p1 et p2 de type "t_pipe" ???


    Citation Envoyé par KenT2004 Voir le message
    Pourrais-tu m'expliquez ces quelques lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    static void trt_sig (int sig)
    {
       signal(sig, trt_sig);
    }
    Dans l'exemple initial, j'utilise des signaux entre le père et son fils pour qu'ils sachent qu'il faut bosser sinon chacun bosserait quand il veut et irait soit chercher soit écrire des données trop tôt. C'est pas grave en soi car si un processus va lire un pipe vide, il sera bloqué jusqu'à ce qu'un autre y écrive et si le processus qui écrit écrit une seconde fois sans que la première ait été lue, la second écriture se bloque jusqu'à ce que le pipe soit dispo pour cette écriture. Mais j'avais envie de m'amuser avec les signaux.
    Donc chaque processus se met en pause() ce qui le bloque et il se débloque dès qu'un signal est reçu (ce qui se passe quand l'autre processus fait un kill(..., SIGALRM)).
    Malheureusement, quand un processus reçoit un signal, il se termine et là ce n'est pas souhaité. Donc il faut prémunir le processus contre ce comportement. C'est le cas de la fonction "signal()". Quand elle est appelée, elle arme un aiguillage vers la fonction "trt_sig". Et si, bien plus tard au cours de son déroulement, le processus reçoit le signal SIGALRM, alors il ne se termine plus mais part vers la fonction en question, exécute son code et revient là où il en était.
    Mais quand cet appel se passe, l'aiguillage est désarmé. Donc si le processus reçoit de nouveau un signal une 2° fois, il refait comme c'était prévu au départ => il s'arrête.
    Seule solution => quand la fonction est exécutée, elle réarme elle-même l'aiguillage vers elle-même d'où la ligne signal(sig, trt_sig), le paramètre "sig" étant le signal qui a déclanché l'appel de la fonction (dans ce cas SIGALRM).

    Citation Envoyé par KenT2004 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
             case -1: 
                fprintf (stderr, "ligne %u - fork() - %s\n", __LINE__,
                         strerror(errno));
                ret = EXIT_FAILURE;
    Si le fork ne peut pas créer de processus fils, il renvoie -1. Dans ce cas j'affiche le message système indiquant la cause de l'échec et je quitte le prog par un exit(). Nicolas Sitbon préfère positionner une variable avec une valeur particulière et ne la sortir qu'à la fin du main car certaines règles d'écriture préconisent de n'avoir pour chaque fonction qu'un seul et unique point de sortie. Pour ma part je pense que les bons programmeurs obéissent aux règles mais que les programmeurs brillant les transgressent parfois...

    Citation Envoyé par KenT2004 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                int status;        
                signal (SIGALRM, trt_sig);
    Il s'agit du premier armement de l'aiguillage sans lequel le processus s'arrètera lorsqu'il recevra le signal SIGALRM
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 40
    Par défaut
    @ Sve@r : Le but de son travail est d'avoir un programme unique qui puisse suivant un appel différent arriver à faire communiquer deux instances de ce même programme.

    En somme, son but final est d'avoir deux consoles avec deux fois le même programme mais ayant eu des appels différents. Le premier sera appelé comme ceci : ./prog fifo1 fifo2 .
    Alors que le second aura une inversion d'arguments donc : ./prog fifo2 fifo1 .

    Ce qui se passera dans les deux appels est que le programme envoi de la première console parlera avec le programme réception de la seconde par la fifo1 par exemple alors que le programme envoi de la seconde console parlera par la fifo2 avec le programme réception de la première console. (ici, programme envoi = fonction père du programme final. programme réception = fonction fils du programme final)

    Je sais pas si j'ai pu éclairer ta lanterne !

    Ps : j'ai codé le problème demandé et je voulais savoir si l'un d'entre vous pourrait me dire ce que le code vaut ! Bien sûr je pourrais le poster aux yeux de tous mais où serait l'utilité pour le P.O.

  20. #20
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 839
    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 839
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par AureK Voir le message
    @ Sve@r : Le but de son travail est d'avoir un programme unique qui puisse suivant un appel différent arriver à faire communiquer deux instances de ce même programme.

    En somme, son but final est d'avoir deux consoles avec deux fois le même programme mais ayant eu des appels différents. Le premier sera appelé comme ceci : ./prog fifo1 fifo2 .
    Alors que le second aura une inversion d'arguments donc : ./prog fifo2 fifo1 .

    Ce qui se passera dans les deux appels est que le programme envoi de la première console parlera avec le programme réception de la seconde par la fifo1 par exemple alors que le programme envoi de la seconde console parlera par la fifo2 avec le programme réception de la première console. (ici, programme envoi = fonction père du programme final. programme réception = fonction fils du programme final)

    Je sais pas si j'ai pu éclairer ta lanterne !
    C'est très clair mais donc ce n'est pas un père/fils comme il le dit quand il dit que ça correspond au point 2 qui est, je le reprends:
    2) soit il s'agit d'un source qui va générer plusieurs processus (à la façon de mon exemple initial) et chaque processus pourra gérer sa partie => dans ce cas tu peux rester avec les pipes nommés ou utiliser des pipes mémoires.
    Ce serait plus selon l'hypothèse 3 qui est:
    3) soit il est réellement demandé de n'avoir qu'un source qui fasse les 2 actions => dans ce cas tu programmes une fonction t1() qui fera l'action de T1, une fonction t2() qui fera l'action de T2 et un main() qui détecte lors du lancement si tu le lances en tant que T1 ou en tant que T2 et qui, selon le cas, appelle t1() ou t2()
    Citation Envoyé par AureK Voir le message
    Ps : j'ai codé le problème demandé et je voulais savoir si l'un d'entre vous pourrait me dire ce que le code vaut ! Bien sûr je pourrais le poster aux yeux de tous mais où serait l'utilité pour le P.O.
    Envoie-le moi en private
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Programme client/serveur avec FIFO
    Par JBouchard dans le forum Débuter
    Réponses: 3
    Dernier message: 27/11/2012, 16h21
  2. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  3. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  4. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

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