Poziv sustava cijevi u C

Pipe System Call C



cijev() je funkcija sustava Linux. The cijev() Sustavna funkcija koristi se za otvaranje deskriptora datoteka koji se koriste za komunikaciju između različitih Linux procesa. Ukratko, cijev() funkcija se koristi za međuprocesnu komunikaciju u Linuxu. U ovom članku pokazat ću vam kako se koristi sustav pipe () u Linuxu. Dakle, krenimo.

Sintaksa datoteke cijev() funkcija je:







intcijev(intpipefd[2]);

Ovdje funkcija pipe () stvara jednosmjerni kanal podataka za međuprocesnu komunikaciju. Prolaziš u int (Cijeli broj) niz polja pipefd koji se sastoji od 2 elementa niza u funkcijskoj cijevi (). Tada funkcija pipe () stvara dva deskriptora datoteke u pipefd nizu.



Prvi element pipefd niz, pipefd [0] služi za čitanje podataka iz cijevi.



Drugi element pipefd niz, pipefd [1] koristi se za upisivanje podataka u cijev.





Uspješno, funkcija pipe () vraća 0. Ako dođe do pogreške tijekom inicijalizacije cijevi, tada funkcija pipe () vraća -1.

Funkcija pipe () definirana je u zaglavlju unistd.h . Da biste koristili pipe () funkciju u svom C programu, morate uključiti zaglavlje unistd.h kako slijedi:



#uključi

Za više informacija o funkciji sustava pipe (), provjerite stranicu stranice pipe () sa sljedećom naredbom:

$ čovjek2cijev
Glavna stranica cijevi().

Primjer 1:

Za prvi primjer stvorite novu izvornu datoteku C. 1_pipe.c i upišite sljedeće redove kodova.

#uključi
#uključi
#uključi

intglavni(poništiti) {
intpipefds[2];

ako(cijev(pipefds) == -1) {
perror ('cijev');
Izlaz (EXIT_FAILURE);
}

printf ('Pročitajte vrijednost deskriptora datoteke: %d n',pipefds[0]);
printf ('Vrijednost deskriptora zapisa datoteke: %d n',pipefds[1]);

povratakEXIT_SUCCESS;
}

Ovdje sam uključio datoteku zaglavlja pipe () unistd.h prvo sljedećim retkom.

#uključi

Zatim, u glavni() funkciju, definirao sam pipefds dva elementa cijeli broj sa sljedećim retkom.

intpipefds[2];

Zatim sam pokrenuo funkciju pipe () za inicijalizaciju niza deskriptora datoteka pipefds kako slijedi.

cijev(pipefds)

Također sam provjerio ima li grešaka koristeći povratnu vrijednost funkcije pipe (). Koristio sam Izlaz() funkciju za prekid programa u slučaju da funkcija cijevi ne uspije.

ako(cijev(pipefds) == -1) {
perror ('cijev');
Izlaz (EXIT_FAILURE);
}

Zatim sam ispisao vrijednost opisa datoteka cijevi čitanja i pisanja pipefds [0] i pipefds [1] odnosno.

printf ('Pročitajte vrijednost deskriptora datoteke: %d n',pipefds[0]);
printf ('Vrijednost deskriptora zapisa datoteke: %d n',pipefds[1]);

Ako pokrenete program, trebali biste vidjeti sljedeći izlaz. Kao što vidite, vrijednost opisa datoteke čitanja cijevi cijevi pipefds [0] je 3 i napisati deskriptor datoteke cijevi pipefds [1] je 4 .

Primjer 2:

Napravite drugu izvornu datoteku C. 2_pipe.c i upišite sljedeće redove kodova.

#uključi
#uključi
#uključi
#uključi

intglavni(poništiti) {
intpipefds[2];
charpufer[5];

ako(cijev(pipefds) == -1) {
perror ('cijev');
Izlaz (EXIT_FAILURE);
}

char *pribadača= '4128 0';

printf ('Zapisivanje PIN -a u cijev ... n');
pisati(pipefds[1],pribadača, 5);
printf ('Gotovo. n n');

printf ('Čitanje PIN -a s cijevi ... n');
čitati(pipefds[0],pufer, 5);
printf ('Gotovo. n n');

printf ('PIN iz cijevi: %s n',pufer);

povratakEXIT_SUCCESS;
}

Ovaj program vam u osnovi pokazuje kako pisati u cijev i čitati podatke koje ste zapisali iz cijevi.

Ovdje sam spremio PIN od 4 znaka u char nizu. Duljina niza je 5 (uključujući NULL znak 0).

char *pribadača= '4128 0';

Svaki ASCII znak ima 1 bajt u C. Dakle, da biste poslali 4 -znamenkasti PIN kroz cijev, morate unijeti 5 bajtova (4 + 1 NULL znak) podataka u cijev.

Za pisanje 5 bajtova podataka ( pribadača ) u cijev, upotrijebio sam pisati() funkciju pomoću deskriptora datoteke zapisa cijevi pipefds [1] kako slijedi.

pisati(pipefds[1],pribadača, 5);

Sad kad imam neke podatke u cijevi, mogu ih pročitati iz cijevi pomoću čitati() funkciju u deskriptoru datoteke čitanja cijevi pipefds [0] . Kako sam napisao 5 bajtova podataka ( pribadača ) u cijev ću čitati i 5 bajtova podataka iz cijevi. Očitani podaci bit će pohranjeni u pufer niz znakova. Kako ću čitati 5 bajtova podataka iz cijevi, pufer niz znakova mora imati najmanje 5 bajtova.

Ja sam definirao pufer niz znakova na početku glavni() funkcija.

charpufer[5];

Sada mogu pročitati PIN iz cijevi i spremiti ga u pufer niz sa sljedećim retkom.

čitati(pipefds[0],pufer, 5);

Sada kada sam pročitao PIN iz cijevi, mogu ga ispisati pomoću printf () funkcionirati kao i obično.

printf ('PIN iz cijevi: %s n',pufer);

Nakon što pokrenem program, prikazuje se ispravan izlaz kao što vidite.

Primjer 3:

Napravite novu izvornu datoteku C. 3_pipe.c kao tip u sljedećim redovima kodova.

#uključi
#uključi
#uključi
#uključi
#uključi
intglavni(poništiti) {
intpipefds[2];
char *pribadača;
charpufer[5];

ako(cijev(pipefds) == -1) {
perror ('cijev');
Izlaz (EXIT_FAILURE);
}

pid_t pid=vilica();

ako(pid== 0) { // u podređenom procesu
pribadača= '4821 0'; // PIN za slanje
Zatvoriti(pipefds[0]); // zatvori čitanje fd
pisati(pipefds[1],pribadača, 5); // upis PIN -a u kanal

printf ('Generiranje PIN -a kod djeteta i slanje roditelju ... n');
spavati(2); // namjerno odgađanje
Izlaz (EXIT_SUCCESS);
}

ako(pid> 0) { // u glavnom procesu
čekati(NULL); // pričekajte da se podređeni proces završi
Zatvoriti(pipefds[1]); // zatvori piši fd
čitati(pipefds[0],pufer, 5); // očitavanje PIN -a iz cijevi
Zatvoriti(pipefds[0]); // zatvori čitanje fd

printf ('Roditelj je primio PIN'%s ' n',pufer);
}

povratakEXIT_SUCCESS;
}

U ovom primjeru sam vam pokazao kako koristiti cijev za međuprocesnu komunikaciju. Poslao sam PIN iz podređenog procesa u roditeljski proces pomoću kanala. Zatim pročitajte PIN iz cijevi u roditeljskom procesu i ispišite ga iz nadređenog procesa.

Prvo sam stvorio podređeni proces pomoću funkcije fork ().

pid_t pid=vilica();

Zatim, u procesu djeteta ( pid == 0 ), Napisao sam PIN cijevi pomoću pisati() funkcija.

pisati(pipefds[1],pribadača, 5);

Nakon što se PIN upiše u cijev iz podređenog procesa, roditeljski proces ( pid> 0 ) pročitajte ga iz cijevi pomoću čitati() funkcija.

čitati(pipefds[0],pufer, 5);

Zatim je roditeljski proces ispisao PIN pomoću printf () funkcionirati kao i obično.

printf ('Roditelj je primio PIN'%s ' n',pufer);

Kao što vidite, pokretanje programa daje očekivani rezultat.

Primjer 4:

Napravite novu izvornu datoteku C. 4_pipe.c kao tip u sljedećim redovima kodova.

#uključi
#uključi
#uključi
#uključi
#uključi

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

poništitigetPIN(charpribadača[PIN_LENGTH+ 1]) {
srand (getpid() +getppid());

pribadača[0] = 49 + red () % 7;

za(inti= 1;i<PIN_LENGTH;i++) {
pribadača[i] = 48 + red () % 7;
}

pribadača[PIN_LENGTH] = ' 0';
}


intglavni(poništiti) {
dok(1) {
intpipefds[2];
charpribadača[PIN_LENGTH+ 1];
charpufer[PIN_LENGTH+ 1];

cijev(pipefds);

pid_t pid=vilica();

ako(pid== 0) {
getPIN(pribadača); // generiranje PIN -a
Zatvoriti(pipefds[0]); // zatvori čitanje fd
pisati(pipefds[1],pribadača,PIN_LENGTH+ 1); // upis PIN -a u kanal

printf ('Generiranje PIN -a kod djeteta i slanje roditelju ... n');

spavati(PIN_WAIT_INTERVAL); // namjerno odgađanje generiranja PIN -a.

Izlaz (EXIT_SUCCESS);
}

ako(pid> 0) {
čekati(NULL); // čekanje da dijete završi

Zatvoriti(pipefds[1]); // zatvori piši fd
čitati(pipefds[0],pufer,PIN_LENGTH+ 1); // očitavanje PIN -a iz cijevi
Zatvoriti(pipefds[0]); // zatvori čitanje fd
printf ('Roditelj je primio PIN'%s 'od djeteta. n n',pufer);
}
}

povratakEXIT_SUCCESS;
}

Ovaj primjer je isti kao Primjer 3 . Jedina razlika je u tome što ovaj program kontinuirano stvara podređeni proces, generira PIN u podređenom procesu i šalje PIN roditeljskom procesu pomoću kanala.

Roditeljski proces tada čita PIN iz cijevi i ispisuje ga.

Ovaj program generira novi PIN_LENGTH PIN svakih PIN_WAIT_INTERVAL sekundi.

Kao što vidite, program radi prema očekivanjima.

Program možete zaustaviti samo pritiskom na + C .

Dakle, ovako koristite pipe () sistemski poziv u programskom jeziku C. Hvala što ste pročitali ovaj članak.