Лучшим решением является использование временных файлов. Это делает код читаемым и простым для понимания, когда подстановка процесса невозможна.
tmpfile=$(mktemp)
producer | tee "$tmpfile" | consumer1
consumer2 <"$tmpfile"
rm -f "$tmpfile"
или даже
tmpfile=$(mktemp)
producer >"$tmpfile"
consumer1 <"$tmpfile"
consumer2 <"$tmpfile"
rm -f "$tmpfile"
После личного тестирования выяснилось, что только вызывающий поток усыпляется, а не какие-либо другие потоки. Пока один поток ждал во время заблокированного чтения, другие потоки все еще были активны.