глава 26
Взаємодія процесів в Linux
26.1. способи взаємодії
Процеси, як і люди, можуть "спілкуватися" між собою, тобто обмінюватися інформацією. У розділі 3 ми побіжно розглянули два засоби взаємодії між процесами (IPC, Inter-Process Communication); напівдуплексні канали (конвеєри) і сигнали, але в UNIX-системах таких засобів значно більше. У цьому розділі я перерахую інші засоби IPC і покажу, як використовувати їх в програмному коді.
З давніх часів існують іменовані канали FIFO (First In - First Out) і мережеві гнізда (сокети). Разом з конвеєрами і сигналами вони складають IPC типу BSD. Компанія ATT разом з операційною системою System V запропонувала три нових види IPC:
В операційній системі Linux підтримуються обидва типи IPC - System V і BSD, тобто в Linux ми можемо використовувати всі перераховані вище способи IPC.
26.2. напівдуплексні канали
Нагадаю, що канал - це спосіб зв'язку стандартного виведення одного процесу зі стандартним введенням іншого. Канали - старожили UNIX: вони з'явилися ще в самих перших версіях UNIX. Напівдуплексні канали дозволяють обмінюватися інформацією тільки в одному напрямку. Якщо процес-предок передає інформацію зі свого стандартного виводу на стандартний ввід нащадка - це приклад полудуплексного каналу.
Що таке перенаправлення вводу / виводу і як його використовувати з командного рядка, ви вже знаєте (п. 3.4.6). Зараз я покажу, як здійснити перенаправлення програмним шляхом, тобто без втручання користувача.
FILE * popen (const char * команда, const char * режім_доступа);
Виклик popen () повертає покажчик FILE * або порожній покажчик NULL, якщо виклик не вдався. Так само, як і при роботі з звичайними файлами, після завершення операції введення / виводу ви повинні закрити канал викликом pclose (). Під час роботи з потоком рекомендую використовувати виклик fflush (). щоб запобігти затримки через буферизації.
Тепер кілька простих прикладів. Припустимо, що нам потрібно вивести на стандартний висновок імена всіх текстових файлів, що містяться в поточному каталозі. Це можна дуже просто зробити за допомогою виклику system ():
Це вже зовсім тривіальне завдання - ми просто виводимо дані, але ніяк не обробляємо їх. Як отримати всі імена текстових файлів і обробити їх в програмі?
FILE * fp = popen ( "ls * .txt", "r");
// в циклі читаємо імена всіх текстових файлів