Ваш родительский поток должен ждать, пока дочерний процесс не будет готов, прежде чем он попытается прочитать из канала. Есть несколько способов сделать это.
Во-первых, вы можете использовать условную переменную. Объявите переменную, к которой могут обращаться оба потока, и установите для нее значение 0
. Ваш дочерний поток установит его на 1
, когда он будет готов для чтения родительским элементом. Родитель будет ждать, пока переменная не изменится на 1
(используя что-то вроде while(!condvar) sleep(1);
), затем он прочитает из канала и сбросит переменную до 0
, чтобы дочерний элемент знал, что родительский элемент закончен.
Другим вариантом является использование формы межпроцессного взаимодействия, например сигналов . Подобно методу условной переменной, дочерний поток выполнит свою работу и после этого отправит сигнал родительскому потоку. Родительский поток будет ждать до тех пор, пока не получит сигнал, прежде чем будет считан из канала, а затем он сможет отправить сигнал обратно дочернему элементу, указывая, что это сделано.
Редактировать: Поскольку вы порождаете дочерний процесс с fork
вместо потоков, вы не можете использовать здесь условную переменную (родительский и дочерний будут иметь отдельные копии).
Вместо этого вы можете использовать функции signal()
и kill()
для передачи сигналов между процессами. Перед разветвлением используйте getpid
, чтобы сохранить копию pid родителя (для дочернего процесса). Также сохраните возвращаемое значение fork
, так как оно будет содержать pid ребенка.
Чтобы отправить сигнал другому процессу, используйте что-то вроде:
kill(parent_pid, SIGUSR1);
Процесс приема должен настроить обработчик сигнала. Например:
int signal_received = 0;
void signal_handler(int signal_num) {
if (signal_num == SIGUSR1)
signal_received = 1;
}
signal(SIGUSR1, signal_handler);
Функция signal_handler
теперь будет вызываться автоматически всякий раз, когда процесс получает номер сигнала SIGUSR1
. Ваш поток будет ждать в цикле, наблюдая за изменением этой переменной, используя что-то вроде:
while (1) { // Signal processing loop
// Wait here for a signal to come in
while (!signal_received) { sleep(1); }
// Wake up and do something
read_from_pipe();
...
signal_received = 0;
}