Одновременное чтение unix fifo из именованного канала оставляет один из процессов незавершенным
Я создал трубу с именем fifo в солярисе, которая построчно записывает содержимое файла в трубу, как показано ниже:
$ mkfifo namepipe
$ cat books.txt
"how to write unix code"
"how to write oracle code"
$ cat books.txt >> namepipe &
у меня есть readpipe.sh
скрипт, который читает именованный канал параллельно следующим образом:
# readpipe.sh
while IFS=',' read var
do
echo var >> log.txt
done < namepipe
Я звоню readpipe.sh
лайк
readpipe.sh &
sleep 2
readpipe.sh &
Я ввел sleep 2
чтобы избежать возникновения гонки, то есть два процесса получают части значений из каждой строки, как процесс 1 получает
"как"
и процесс 2 получает
"написать код Unix"
Проблема, с которой я сталкиваюсь, - это когда все содержимое namepipe
завершен, первый фоновый процесс завершается, а второй продолжает работать без завершения.
Логика в сценарии объявляется простой здесь для ясного понимания. фактический readpipd.sh
делает много мероприятий.
Пожалуйста, помогите мне со знанием
1 ответ
Я ввел сон 2, чтобы избежать возникновения гонки
Во-первых, это не сработает. sleep
явно ничего не синхронизирует.
Во-вторых, вы не можете "поделиться" чтением из канала, если каждый процесс чтения не знает, сколько нужно читать за раз. А также read
в sh
скрипт не даст вам никакого контроля над тем, сколько байтов sh
двоичный на самом деле читает из канала с низким уровнем read()
называть это использует. sh
процесс скорее всего пытается прочитать PIPE_BUF
байты, но он может пытаться читать что угодно, так как на самом деле он просто передает поток. И вы не можете контролировать, сколько он читает.
Например, каждый процесс должен знать, что следующее чтение из канала должно быть 143 байта, а затем он выдает низкоуровневый read( fd, buffer, 143 );
вызов для чтения только 143 байта.
И даже если вы можете контролировать на нижнем уровне, сколько читает каждый процесс, каждый процесс должен знать, сколько читать, чего в этом случае вы не можете знать.
Наличие заранее известного размера чтения необходимо для того, чтобы делать то, что вы хотите, а у вас его нет при использовании скриптов. Однако обратите внимание, что этого может быть недостаточно - даже если вы решите проблему общего читателя, вы можете столкнуться с другими проблемами, пытаясь поделиться читателями.
В этом случае почти наверняка происходит то, что ваш первый скрипт, который запускается, потребляет все данные, переданные в канал, а затем закрывается и продолжает работу, когда данных больше нет. ТОГДА второй скрипт открывает канал и ждет данных - но их нет, поэтому он просто блокирует.