Одновременное чтение 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 байта.

И даже если вы можете контролировать на нижнем уровне, сколько читает каждый процесс, каждый процесс должен знать, сколько читать, чего в этом случае вы не можете знать.

Наличие заранее известного размера чтения необходимо для того, чтобы делать то, что вы хотите, а у вас его нет при использовании скриптов. Однако обратите внимание, что этого может быть недостаточно - даже если вы решите проблему общего читателя, вы можете столкнуться с другими проблемами, пытаясь поделиться читателями.

В этом случае почти наверняка происходит то, что ваш первый скрипт, который запускается, потребляет все данные, переданные в канал, а затем закрывается и продолжает работу, когда данных больше нет. ТОГДА второй скрипт открывает канал и ждет данных - но их нет, поэтому он просто блокирует.

Другие вопросы по тегам