Труба є середовищем для зв'язку між процесами. Один процес записує дані в трубу, а інший процес читає дані з труби. У цій статті ми побачимо, як функція pipe () використовується для реалізації концепції за допомогою мови C.
Про трубу
У каналі дані зберігаються в порядку FIFO, що означає послідовне записування даних на один кінець каналу та зчитування даних з іншого кінця каналу в тому ж послідовному порядку.
Якщо будь-який процес читає з конвеєра, але жоден інший процес ще не записав у конвеєр, тоді read повертає кінець файлу. Якщо процес хоче записати в конвеєр, але до конвеєра для зчитування не приєднано жодного іншого процесу, це є умовою помилки, і конвеєр генерує сигнал SIGPIPE.
Файл заголовка
#включатиСинтаксис
int-канал (int-файли [2])Аргументи
Ця функція приймає один аргумент, масив із двох цілих чисел (подачі). подачі [0] використовується для зчитування з труби, і подачі [1] використовується для запису в трубу. Процес, який потрібно прочитати з труби, повинен завершитися файли [1], і процес, який потрібно записати в трубу, повинен завершитися подачі [0]. Якщо непотрібні кінці труби явно не закриті, кінець файлу (EOF) ніколи не повернеться.
Повернути значення
На успіх, труба () повертає 0, у разі відмови функція повертає -1.
Наочно ми можемо представити труба () функціонують наступним чином:
Нижче наведено кілька прикладів, що зображують, як використовувати функцію pipe на мові C.
Приклад1
У цьому прикладі ми побачимо, як працює функція pipe. Хоча використовувати трубу в одному процесі не дуже корисно, але ми отримаємо ідею.
// Приклад1.c#включати
#включати
#включати
#включати
int main ()
int n;
int сервіси [2];
буфер символів [1025];
char * message = "Привіт, Світ!";
труба (подана);
писати (сервер [1], повідомлення, strlen (повідомлення));
якщо ((n = зчитування (подані файли [0], буфер, 1024))> = 0)
буфер [n] = 0; // закінчує рядок
printf ("зчитування% d байт з конвеєра:"% s "\ n", n, буфер);
ще
perror ("прочитати");
вихід (0);
Тут ми вперше створили трубу за допомогою труба () Потім функція записується в трубу за допомогою Фільдес [1] кінець. Потім дані були прочитані з іншого кінця труби, який є подачі [0]. Для читання та запису у файл ми звикли читати () і write () функції.
Приклад2
У цьому прикладі ми побачимо, як батьківський та дочірній процеси взаємодіють за допомогою каналу.
// Приклад2.c#включати
#включати
#включати
#включати
#включати
int main ()
int файли [2], нбайт;
pid_t Childpid;
char string [] = "Привіт, світе!\ n ";
буфер зчитування [80];
труба (подана);
if ((childpid = fork ()) == -1)
perror ("вилка");
вихід (1);
якщо (Childpid == 0)
close (сервер [0]); // Дочірній процес не потребує цього кінця каналу
/ * Надішліть "рядок" через вихідну сторону труби * /
запис (подані файли [1], рядок, (strlen (рядок) +1));
вихід (0);
ще
/ * Батьківський процес закриває вихідну сторону труби * /
close (сервер [1]); // Батьківському процесу цей кінець каналу не потрібен
/ * Зчитування в рядку з труби * /
nbytes = читання (подані файли [0], буфер читання, розмір (буфер читання));
printf ("Читати рядок:% s", буфер читання);
повернення (0);
Спочатку було створено одну трубу з використанням функції pipe, потім дочірній процес роздвоївся. Потім дочірній процес закриває кінець зчитування та записує в трубу. Батьківський процес закриває кінець запису, зчитує з конвеєра і відображає його. Тут потік даних - це лише один шлях від дочірнього до батьківського.
Висновок:
труба () це потужний системний дзвінок у Linux. У цій статті ми бачили лише односторонній потік даних, один процес пише, а інший процес читає, створюючи дві труби, ми також можемо досягти двонаправленого потоку даних.