Wywołanie systemu rur w C

Pipe System Call C



rura() jest funkcją systemu Linux. ten rura() funkcja system służy do otwierania deskryptorów plików, które są używane do komunikacji między różnymi procesami Linuksa. Krótko mówiąc, rura() funkcja służy do komunikacji między procesami w systemie Linux. W tym artykule pokażę, jak używać funkcji systemowej pipe() w Linuksie. Więc zacznijmy.

Składnia rura() funkcja to:







intrura(intpotok[2]);

Tutaj funkcja pipe() tworzy jednokierunkowy kanał danych do komunikacji między procesami. Przechodzisz w int (Liczba całkowita) tablica typu potok składający się z 2 elementów tablicy do funkcji pipe(). Następnie funkcja pipe() tworzy dwa deskryptory plików w potok szyk.



Pierwszy element potok szyk, pipefd[0] służy do odczytywania danych z potoku.



Drugi element potok szyk, potok[1] służy do zapisywania danych do potoku.





W przypadku powodzenia funkcja pipe() zwraca 0. Jeśli podczas inicjalizacji potoku wystąpi błąd, funkcja pipe() zwraca -1.

Funkcja pipe() jest zdefiniowana w nagłówku unistd.h . Aby użyć funkcji pipe() w programie C, musisz dołączyć nagłówek unistd.h następująco:



#włączać

Więcej informacji na temat funkcji systemowej pipe() można znaleźć na stronie podręcznika funkcji pipe() za pomocą następującego polecenia:

$ mężczyzna2rura
Strona podręcznika użytkownika pipe().

Przykład 1:

W pierwszym przykładzie utwórz nowy plik źródłowy C 1_pipe.c i wpisz następujące wiersze kodów.

#włączać
#włączać
#włączać

intGłówny(próżnia) {
intpotoki[2];

Jeśli(rura(potoki) == -1) {
błąd ('rura');
Wyjście (EXIT_FAILURE);
}

printf ('Odczytaj wartość deskryptora pliku: %d ',potoki[0]);
printf ('Zapisz wartość deskryptora pliku: %d ',potoki[1]);

powrótEXIT_SUCCESS;
}

Tutaj dołączyłem plik nagłówkowy pipe() unistd.h najpierw z następującą linią.

#włączać

Następnie w Główny() funkcji, zdefiniowałem potoki dwuelementowa tablica liczb całkowitych z następującym wierszem.

intpotoki[2];

Następnie uruchomiłem funkcję pipe(), aby zainicjować tablicę deskryptorów plików potoki następująco.

rura(potoki)

Sprawdziłem również pod kątem błędów, używając wartości zwracanej przez funkcję pipe(). użyłem Wyjście() funkcja do zakończenia programu w przypadku niepowodzenia funkcji potoku.

Jeśli(rura(potoki) == -1) {
błąd ('rura');
Wyjście (EXIT_FAILURE);
}

Następnie wydrukowałem wartość deskryptorów plików potoku odczytu i zapisu potoki[0] oraz potoki[1] odpowiednio.

printf ('Odczytaj wartość deskryptora pliku: %d ',potoki[0]);
printf ('Zapisz wartość deskryptora pliku: %d ',potoki[1]);

Jeśli uruchomisz program, powinieneś zobaczyć następujące dane wyjściowe. Jak widać, wartość deskryptora pliku potoku odczytu potoki[0] jest 3 i napisz deskryptor pliku potoku potoki[1] jest 4 .

Przykład 2:

Utwórz kolejny plik źródłowy C 2_pipe.c i wpisz następujące wiersze kodów.

#włączać
#włączać
#włączać
#włączać

intGłówny(próżnia) {
intpotoki[2];
zwęglaćbufor[5];

Jeśli(rura(potoki) == -1) {
błąd ('rura');
Wyjście (EXIT_FAILURE);
}

zwęglać *Szpilka= „4128” 0';

printf ('Zapisywanie kodu PIN do rury... ');
pisać(potoki[1],Szpilka, 5);
printf ('Gotowe. ');

printf ('Odczytywanie kodu PIN z potoku... ');
czytać(potoki[0],bufor, 5);
printf ('Gotowe. ');

printf ('PIN z potoku: %s ',bufor);

powrótEXIT_SUCCESS;
}

Ten program zasadniczo pokazuje, jak pisać do potoku i czytać dane, które napisałeś z potoku.

Tutaj zapisałem 4-znakowy kod PIN w zwęglać szyk. Długość tablicy wynosi 5 (łącznie ze znakiem NULL ).

zwęglać *Szpilka= „4128” 0';

Każdy znak ASCII ma rozmiar 1 bajta w C. Tak więc, aby wysłać 4-cyfrowy kod PIN przez potok, należy wpisać do potoku 5 bajtów (4 + 1 znak NULL) danych.

Aby zapisać 5 bajtów danych ( Szpilka ) do rury, użyłem pisać() funkcja za pomocą deskryptora pliku potoku zapisu potoki[1] następująco.

pisać(potoki[1],Szpilka, 5);

Teraz, gdy mam już jakieś dane w potoku, mogę je odczytać z potoku za pomocą czytać() funkcja na deskryptorze pliku potoku odczytu potoki[0] . Jak napisałem 5 bajtów danych ( Szpilka ) do potoku, będę również odczytywał 5 bajtów danych z potoku. Odczytane dane będą przechowywane w bufor tablica znaków. Jak będę odczytywał 5 bajtów danych z potoku, bufor tablica znaków musi mieć co najmniej 5 bajtów.

zdefiniowałem bufor tablica znaków na początku Główny() funkcjonować.

zwęglaćbufor[5];

Teraz mogę odczytać PIN z rury i przechowywać go w bufor tablica z następującym wierszem.

czytać(potoki[0],bufor, 5);

Teraz, gdy odczytałem kod PIN z potoku, mogę go wydrukować za pomocą printf() działać jak zwykle.

printf ('PIN z potoku: %s ',bufor);

Po uruchomieniu programu wyświetlane są prawidłowe dane wyjściowe, jak widać.

Przykład 3:

Utwórz nowy plik źródłowy C 3_pipe.c wpisz następujące wiersze kodów.

#włączać
#włączać
#włączać
#włączać
#włączać
intGłówny(próżnia) {
intpotoki[2];
zwęglać *Szpilka;
zwęglaćbufor[5];

Jeśli(rura(potoki) == -1) {
błąd ('rura');
Wyjście (EXIT_FAILURE);
}

pid_t pid=widelec();

Jeśli(pid== 0) { // w procesie potomnym
Szpilka= „4821” 0'; // PIN do wysłania
blisko(potoki[0]); // zamknij odczyt fd
pisać(potoki[1],Szpilka, 5); // napisz PIN do potoku

printf ('Generowanie kodu PIN u dziecka i wysyłanie do rodzica... ');
spać(2); // celowe opóźnienie
Wyjście (EXIT_SUCCESS);
}

Jeśli(pid> 0) { // w głównym procesie
czekać(ZERO); // poczekaj na zakończenie procesu potomnego
blisko(potoki[1]); // zamknij zapis fd
czytać(potoki[0],bufor, 5); // odczytaj PIN z potoku
blisko(potoki[0]); // zamknij odczyt fd

printf ('Rodzic otrzymał PIN '%s' ',bufor);
}

powrótEXIT_SUCCESS;
}

W tym przykładzie pokazałem, jak używać potoku do komunikacji między procesami. Wysłałem kod PIN z procesu podrzędnego do procesu nadrzędnego za pomocą potoku. Następnie odczytaj kod PIN z potoku w procesie nadrzędnym i wydrukuj go z procesu nadrzędnego.

Najpierw stworzyłem proces potomny za pomocą funkcji fork().

pid_t pid=widelec();

Następnie w procesie potomnym ( pid == 0 ), napisałem PIN do rury za pomocą pisać() funkcjonować.

pisać(potoki[1],Szpilka, 5);

Po zapisaniu kodu PIN do potoku z procesu podrzędnego proces nadrzędny ( pid > 0 ) odczytaj go z rury za pomocą czytać() funkcjonować.

czytać(potoki[0],bufor, 5);

Następnie proces nadrzędny wydrukował kod PIN za pomocą printf() działać jak zwykle.

printf ('Rodzic otrzymał PIN '%s' ',bufor);

Jak widać, uruchomienie programu daje oczekiwany rezultat.

Przykład 4:

Utwórz nowy plik źródłowy C 4_pipe.c wpisz następujące wiersze kodów.

#włączać
#włączać
#włączać
#włączać
#włączać

#define PIN_LENGTH 4
#define PIN_WAIT_INTERVAL 2

próżniazdobądź PIN(zwęglaćSzpilka[PIN_LENGTH+ 1]) {
srand (getpid() +getppid());

Szpilka[0] = 49 + wiersz () % 7;

dla(inti= 1;i<PIN_LENGTH;i++) {
Szpilka[i] = 48 + wiersz () % 7;
}

Szpilka[PIN_LENGTH] = ' 0';
}


intGłówny(próżnia) {
podczas(1) {
intpotoki[2];
zwęglaćSzpilka[PIN_LENGTH+ 1];
zwęglaćbufor[PIN_LENGTH+ 1];

rura(potoki);

pid_t pid=widelec();

Jeśli(pid== 0) {
zdobądź PIN(Szpilka); // wygeneruj PIN
blisko(potoki[0]); // zamknij odczyt fd
pisać(potoki[1],Szpilka,PIN_LENGTH+ 1); // napisz PIN do potoku

printf ('Generowanie kodu PIN u dziecka i wysyłanie do rodzica... ');

spać(PIN_WAIT_INTERVAL); // celowe opóźnianie generowania kodu PIN.

Wyjście (EXIT_SUCCESS);
}

Jeśli(pid> 0) {
czekać(ZERO); // czekanie, aż dziecko skończy

blisko(potoki[1]); // zamknij zapis fd
czytać(potoki[0],bufor,PIN_LENGTH+ 1); // odczytaj PIN z potoku
blisko(potoki[0]); // zamknij odczyt fd
printf ('Rodzic otrzymał PIN '%s' od dziecka. ',bufor);
}
}

powrótEXIT_SUCCESS;
}

Ten przykład jest taki sam jak Przykład 3 . Jedyną różnicą jest to, że ten program stale tworzy proces potomny, generuje kod PIN w procesie potomnym i wysyła kod PIN do procesu nadrzędnego za pomocą potoku.

Następnie proces nadrzędny odczytuje kod PIN z potoku i drukuje go.

Ten program generuje nowy PIN_LENGTH PIN co PIN_WAIT_INTERVAL sekund.

Jak widać, program działa zgodnie z oczekiwaniami.

Program można zatrzymać tylko naciskając + C .

Tak więc używasz wywołania systemowego pipe() w języku programowania C. Dziękuję za przeczytanie tego artykułu.