Différences entre versions de « C pipe »
Aller à la navigation
Aller à la recherche
(Page créée avec « = Introduction = Un tube est un canal par lequel les informations circulent de manière uni-directionnel. Un processus écrit dans l'entrée du tube et un autre processus... ») |
|||
| Ligne 1 : | Ligne 1 : | ||
= Introduction = | = Introduction = | ||
Un tube est un canal par lequel les informations circulent de manière uni-directionnel. Un processus écrit dans l'entrée du tube et un autre processus lit les informations en sortie. | Un tube est un canal par lequel les informations circulent de manière uni-directionnel. Un processus écrit dans l'entrée du tube et un autre processus lit les informations en sortie. | ||
| + | |||
| + | = Manipulation des tubes = | ||
| + | == Création == | ||
| + | La première étape est la création d'un tube: | ||
| + | <source lang="c"> | ||
| + | #include <unistd.h> | ||
| + | |||
| + | int tube[2]; | ||
| + | |||
| + | int pipe(int tube[2]); | ||
| + | </source> | ||
| + | |||
| + | *tube[0] → contiendra le fichier descripteur de l'extrémité de lecture | ||
| + | *tube[1] → contiendra le fichier descripteur de l'extrémité d'écriture | ||
| + | *Le retour sera : | ||
| + | ** '0' si tout s'est bien passé | ||
| + | ** '1' si une erreur survient et errno est positionné | ||
| + | |||
| + | == Écriture == | ||
| + | Pour écrire dans un tube : | ||
| + | <source lang="c"> | ||
| + | #include <unistd.h> | ||
| + | |||
| + | ssize_t write(int tube[0], const void *message, size_t longueur); | ||
| + | </source> | ||
| + | *tube[0] → le fichier descripteur de l'extrémité d'écriture | ||
| + | *message → le message à écrire | ||
| + | *longueur → la longueur du message | ||
| + | *ssize_t → le nombre d'octets écrits | ||
| + | == Lecture == | ||
| + | Pour lire dans un tube : | ||
| + | <source lang="c"> | ||
| + | #include <unistd.h> | ||
| + | |||
| + | ssize_t read(int tube[1], void *message, size_t longueur); | ||
| + | </source> | ||
| + | *tube[1] → le fichier descripteur de l'extrémité de lecture | ||
| + | *message → un tableau de caractère qui contiendra le message à lire | ||
| + | *longueur → la longueur du message à lire | ||
| + | *ssize_t → le nombre d'octets lus | ||
| + | |||
| + | = Utilisation uni-directionnel = | ||
| + | Ci-dessous un exemple qui permet au père de communiquer avec ces fils: | ||
| + | <source lang="c"> | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <unistd.h> | ||
| + | #include <sys/types.h> | ||
| + | #include <sys/wait.h> | ||
| + | #include <string.h> | ||
| + | |||
| + | // Nombre total de thread | ||
| + | #define NB_FORK 2 | ||
| + | // Taille du message | ||
| + | #define LENGTH_MSG 30 | ||
| + | // Tableau contenant le message | ||
| + | char message[LENGTH_MSG] = ""; | ||
| + | |||
| + | // Fonction exécutée dans le fork | ||
| + | void job(int * tube) { | ||
| + | int tid = getpid(); | ||
| + | // timer pour attendre maximum 5 secondes | ||
| + | int i = 5; | ||
| + | while (i > 0) { | ||
| + | // lecture dans le tube | ||
| + | if (read(*tube, message, LENGTH_MSG) > 0) { | ||
| + | printf("Message du processus [%i] : %s", tid, message); | ||
| + | break; | ||
| + | } | ||
| + | sleep(1); | ||
| + | } | ||
| + | exit(EXIT_SUCCESS); | ||
| + | } | ||
| + | // Fonction qui attend chacun des processus fils | ||
| + | void waitForAll() { | ||
| + | int status; | ||
| + | pid_t pid; | ||
| + | int n = 0; | ||
| + | while (n < NB_FORK) { | ||
| + | pid = wait(&status); | ||
| + | n++; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | int main() { | ||
| + | for (int i = 0; i < NB_FORK; i++) { | ||
| + | int tube[2]; | ||
| + | pipe(tube); | ||
| + | pid_t pid = fork(); | ||
| + | if (pid == -1) { | ||
| + | // Il y a une erreur | ||
| + | perror("fork"); | ||
| + | return EXIT_FAILURE; | ||
| + | } else if (pid == 0) { | ||
| + | // On est dans le fils | ||
| + | job(&tube[0]); | ||
| + | } else { | ||
| + | // On est dans le père | ||
| + | // Ecriture du message dans le tableau | ||
| + | sprintf(message, "Fork [%i], je suis ton père !\n", pid); | ||
| + | // Ecriture du message dans le tube | ||
| + | write(tube[1], message, LENGTH_MSG); | ||
| + | } | ||
| + | } | ||
| + | waitForAll(); | ||
| + | return EXIT_SUCCESS; | ||
| + | } | ||
| + | </source> | ||
Version du 17 octobre 2018 à 22:50
Introduction
Un tube est un canal par lequel les informations circulent de manière uni-directionnel. Un processus écrit dans l'entrée du tube et un autre processus lit les informations en sortie.
Manipulation des tubes
Création
La première étape est la création d'un tube:
#include <unistd.h>
int tube[2];
int pipe(int tube[2]);
- tube[0] → contiendra le fichier descripteur de l'extrémité de lecture
- tube[1] → contiendra le fichier descripteur de l'extrémité d'écriture
- Le retour sera :
- '0' si tout s'est bien passé
- '1' si une erreur survient et errno est positionné
Écriture
Pour écrire dans un tube :
#include <unistd.h>
ssize_t write(int tube[0], const void *message, size_t longueur);
- tube[0] → le fichier descripteur de l'extrémité d'écriture
- message → le message à écrire
- longueur → la longueur du message
- ssize_t → le nombre d'octets écrits
Lecture
Pour lire dans un tube :
#include <unistd.h>
ssize_t read(int tube[1], void *message, size_t longueur);
- tube[1] → le fichier descripteur de l'extrémité de lecture
- message → un tableau de caractère qui contiendra le message à lire
- longueur → la longueur du message à lire
- ssize_t → le nombre d'octets lus
Utilisation uni-directionnel
Ci-dessous un exemple qui permet au père de communiquer avec ces fils:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
// Nombre total de thread
#define NB_FORK 2
// Taille du message
#define LENGTH_MSG 30
// Tableau contenant le message
char message[LENGTH_MSG] = "";
// Fonction exécutée dans le fork
void job(int * tube) {
int tid = getpid();
// timer pour attendre maximum 5 secondes
int i = 5;
while (i > 0) {
// lecture dans le tube
if (read(*tube, message, LENGTH_MSG) > 0) {
printf("Message du processus [%i] : %s", tid, message);
break;
}
sleep(1);
}
exit(EXIT_SUCCESS);
}
// Fonction qui attend chacun des processus fils
void waitForAll() {
int status;
pid_t pid;
int n = 0;
while (n < NB_FORK) {
pid = wait(&status);
n++;
}
}
int main() {
for (int i = 0; i < NB_FORK; i++) {
int tube[2];
pipe(tube);
pid_t pid = fork();
if (pid == -1) {
// Il y a une erreur
perror("fork");
return EXIT_FAILURE;
} else if (pid == 0) {
// On est dans le fils
job(&tube[0]);
} else {
// On est dans le père
// Ecriture du message dans le tableau
sprintf(message, "Fork [%i], je suis ton père !\n", pid);
// Ecriture du message dans le tube
write(tube[1], message, LENGTH_MSG);
}
}
waitForAll();
return EXIT_SUCCESS;
}