Truca al sistema de canonades en C.

Pipe System Call C



pipa () és una funció del sistema Linux. El pipa () La funció del sistema s'utilitza per obrir descriptors de fitxers, que s'utilitzen per comunicar-se entre diferents processos de Linux. En resum, el pipa () La funció s'utilitza per a la comunicació entre processos a Linux. En aquest article, us mostraré com utilitzar la funció de sistema pipe () a Linux. Per tant, comencem.

La sintaxi del fitxer pipa () la funció és:







intcanonada(intpipefd[2]);

Aquí, la funció pipe () crea un canal de dades unidireccional per a la comunicació entre processos. Passes en un int Matriu de tipus (enter) pipefd que consta de 2 elements de matriu a la funció de canonada (). A continuació, la funció pipe () crea dos descriptors de fitxers al fitxer pipefd matriu.



El primer element del fitxer pipefd matriu, pipefd [0] s’utilitza per llegir dades de la canonada.



El segon element del fitxer pipefd matriu, pipefd [1] s’utilitza per escriure dades a la canonada.





Si té èxit, la funció pipe () retorna 0. Si es produeix un error durant la inicialització de la canonada, la funció pipe () retorna -1.

La funció pipe () es defineix a la capçalera unistd.h . Per utilitzar la funció pipe () al programa C, heu d’incloure la capçalera unistd.h com segueix:



#incloure

Per obtenir més informació sobre la funció del sistema pipe (), consulteu la pàgina manual de pipe () amb l'ordre següent:

$ home2canonada
La pàgina manual de pipa().

Exemple 1:

Per al primer exemple, creeu un fitxer font C. 1_pipe.c i escriviu les línies de codis següents.

#incloure
#incloure
#incloure

intprincipal(buit) {
intpipefds[2];

si(canonada(pipefds) == -1) {
perror ('pipa');
sortir (EXIT_FAILURE);
}

printf ('Llegeix el valor del descriptor del fitxer:% d n',pipefds[0]);
printf ('Escriu el valor del descriptor del fitxer:% d n',pipefds[1]);

tornarSORTIR_ÈXIT;
}

Aquí he inclòs el fitxer de capçalera de pipe () unistd.h primer amb la línia següent.

#incloure

Després, al main () funció, he definit el fitxer pipefds matriu sencera de dos elements amb la línia següent.

intpipefds[2];

Després, he executat la funció pipe () per inicialitzar la matriu de descriptors de fitxers pipefds com segueix.

canonada(pipefds)

També he comprovat si hi havia errors amb el valor de retorn de la funció pipe (). He utilitzat el sortir () per finalitzar el programa en cas que falla la funció de canonada.

si(canonada(pipefds) == -1) {
perror ('pipa');
sortir (EXIT_FAILURE);
}

Després, vaig imprimir el valor dels descriptors de fitxers de canonades de lectura i escriptura pipefds [0] i pipefds [1] respectivament.

printf ('Llegeix el valor del descriptor del fitxer:% d n',pipefds[0]);
printf ('Escriu el valor del descriptor del fitxer:% d n',pipefds[1]);

Si executeu el programa, hauríeu de veure la següent sortida. Com podeu veure, el valor del descriptor de fitxers de canonades de lectura pipefds [0] és 3 i escriviu el descriptor de fitxers de canonades pipefds [1] és 4 .

Exemple 2:

Creeu un altre fitxer font C. 2_pipe.c i escriviu les línies de codis següents.

#incloure
#incloure
#incloure
#incloure

intprincipal(buit) {
intpipefds[2];
charmemòria intermèdia[5];

si(canonada(pipefds) == -1) {
perror ('pipa');
sortir (EXIT_FAILURE);
}

char *pin= '4128 0';

printf ('S'està escrivint el PIN per canalitzar ... n');
escriure(pipefds[1],pin, 5);
printf (Fet. n n');

printf ('Llegint el PIN des de la canonada ... n');
llegir(pipefds[0],memòria intermèdia, 5);
printf (Fet. n n');

printf (PIN del canal:% s n',memòria intermèdia);

tornarSORTIR_ÈXIT;
}

Aquest programa bàsicament us mostra com escriure a la pipa i llegir les dades que heu escrit de la pipa.

Aquí he emmagatzemat un codi PIN de 4 caràcters en un fitxer char matriu. La longitud de la matriu és 5 (incloent el caràcter NULL 0).

char *pin= '4128 0';

Cada caràcter ASCII té una mida d'1 byte en C. Per tant, per enviar el PIN de 4 dígits a través de la canonada, heu d'escriure 5 bytes (4 + 1 caràcter NULL) de dades a la canonada.

Per escriure 5 bytes de dades ( pin ) a la canonada, he utilitzat el write () funció mitjançant el descriptor de fitxers de canonada d'escriptura pipefds [1] com segueix.

escriure(pipefds[1],pin, 5);

Ara que tinc algunes dades a la canonada, la puc llegir des de la canonada mitjançant el fitxer llegir () funció al descriptor de fitxers de canonades de lectura pipefds [0] . Com he escrit 5 bytes de dades ( pin ) a la canonada, també llegiré 5 bytes de dades de la canonada. Les dades llegides s'emmagatzemaran a memòria intermèdia matriu de caràcters. Com llegiré 5 bytes de dades de la canonada, el fitxer memòria intermèdia la matriu de caràcters ha de tenir com a mínim 5 bytes de longitud.

He definit el memòria intermèdia matriu de caràcters al començament del fitxer main () funció.

charmemòria intermèdia[5];

Ara puc llegir el PIN de la canonada i emmagatzemar-lo al fitxer memòria intermèdia matriu amb la línia següent.

llegir(pipefds[0],memòria intermèdia, 5);

Ara que he llegit el PIN de la canonada, el puc imprimir amb el fitxer printf () funcionar com de costum.

printf (PIN del canal:% s n',memòria intermèdia);

Un cop executat el programa, es mostra la sortida correcta com podeu veure.

Exemple 3:

Creeu un fitxer font C. 3_pipe.c com escriviu a les línies de codis següents.

#incloure
#incloure
#incloure
#incloure
#incloure
intprincipal(buit) {
intpipefds[2];
char *pin;
charmemòria intermèdia[5];

si(canonada(pipefds) == -1) {
perror ('pipa');
sortir (EXIT_FAILURE);
}

pid_t pid=forquilla();

si(pid== 0) { // en procés fill
pin= '4821 0'; // PIN per enviar
Tanca(pipefds[0]); // tancar llegit fd
escriure(pipefds[1],pin, 5); // escriu PIN a la canonada

printf ('Generació de PIN al nen i enviament als pares ... n');
dormir(2); // retard intencionat
sortir (SORTIR_ÈXIT);
}

si(pid> 0) { // en procés principal
espera(NUL); // espera que finalitzi el procés fill
Tanca(pipefds[1]); // tancar escriure fd
llegir(pipefds[0],memòria intermèdia, 5); // llegir PIN des de la canonada
Tanca(pipefds[0]); // tancar llegit fd

printf ('El pare ha rebut el PIN'% s ' n',memòria intermèdia);
}

tornarSORTIR_ÈXIT;
}

En aquest exemple, us vaig mostrar com utilitzar la canonada per a la comunicació entre processos. He enviat un PIN des del procés fill al procés pare mitjançant un canal. A continuació, llegiu el PIN de la canonada del procés pare i imprimiu-lo des del procés pare.

En primer lloc, he creat un procés fill amb la funció fork ().

pid_t pid=forquilla();

Després, en el procés infantil ( pid == 0 ), He escrit el PIN a la canonada amb el fitxer write () funció.

escriure(pipefds[1],pin, 5);

Un cop escrit el PIN a la canonada del procés fill, el procés pare ( pid> 0 ) llegiu-lo des de la canonada amb el fitxer llegir () funció.

llegir(pipefds[0],memòria intermèdia, 5);

A continuació, el procés principal va imprimir el PIN mitjançant printf () funcionar com de costum.

printf ('El pare ha rebut el PIN'% s ' n',memòria intermèdia);

Com podeu veure, executar el programa dóna el resultat esperat.

Exemple 4:

Creeu un fitxer font C. 4_pipe.c com escriviu a les línies de codis següents.

#incloure
#incloure
#incloure
#incloure
#incloure

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

buitgetPIN(charpin[PIN_LENGTH+ 1]) {
srand (getpid() +getppid());

pin[0] = 49 + fila () % 7;

per(intjo= 1;jo<PIN_LENGTH;jo++) {
pin[jo] = 48 + fila () % 7;
}

pin[PIN_LENGTH] = ' 0';
}


intprincipal(buit) {
mentre(1) {
intpipefds[2];
charpin[PIN_LENGTH+ 1];
charmemòria intermèdia[PIN_LENGTH+ 1];

canonada(pipefds);

pid_t pid=forquilla();

si(pid== 0) {
getPIN(pin); // generar PIN
Tanca(pipefds[0]); // tancar llegit fd
escriure(pipefds[1],pin,PIN_LENGTH+ 1); // escriu PIN a la canonada

printf ('Generació de PIN al nen i enviament als pares ... n');

dormir(PIN_WAIT_INTERVAL); // retardar la generació de PIN intencionadament.

sortir (SORTIR_ÈXIT);
}

si(pid> 0) {
espera(NUL); // esperant que acabi el nen

Tanca(pipefds[1]); // tancar escriure fd
llegir(pipefds[0],memòria intermèdia,PIN_LENGTH+ 1); // llegir PIN des de la canonada
Tanca(pipefds[0]); // tancar llegit fd
printf ('El pare ha rebut el PIN'% s 'del nen. n n',memòria intermèdia);
}
}

tornarSORTIR_ÈXIT;
}

Aquest exemple és el mateix que Exemple 3 . L'única diferència és que aquest programa crea contínuament un procés secundari, genera un PIN en el procés secundari i envia el PIN al procés principal mitjançant una canonada.

El procés pare llegeix el PIN de la canonada i l’imprimeix.

Aquest programa genera un nou PIN_LENGTH PIN cada PIN_WAIT_INTERVAL segons.

Com podeu veure, el programa funciona com s’esperava.

Només podeu aturar el programa prement + C .

Així, doncs, és com s’utilitza la trucada del sistema pipe () en llenguatge de programació C. Gràcies per llegir aquest article.