Я пытаюсь распараллелить обработку набора файлов с помощью bash. Я использую именованные каналы для поддержания фиксированного количества процессов и сбора данных из процессов.bash: записывает ли названные каналы атома?
Я предполагаю, что записи в именованный канал являются атомарными, то есть выход другого процесса не смешивается. Это безопасное предположение?
Любые советы приветствуются. Я ограничен использованием bash.
Вот код:
mytask()
{
wItem=$1
#dummy func; process workItem
rt=$RANDOM
st=$rt;
let "rt %= 2"
let "st %= 10"
sleep $st
return $rt
}
parallelizeTask()
{
workList=$1
threadCnt=$2
task=$3
threadSyncPipeD=$4
outputSyncPipeD=$5
ti=0
for workItem in $workList; do
if [ $ti -lt $threadCnt ]; then
{ $task $workItem; if [ $? == 0 ]; then result="success"; else result="failure"; fi; \
echo "$result:$workItem" >&$outputSyncPipeD; echo "$result:$workItem" >&$threadSyncPipeD; } &
((ti++))
continue;
fi
while read n; do
((ti--))
break;
done <&$threadSyncPipeD
{ $task $workItem; if [ $? == 0 ]; then result="success"; else result="failure"; fi; \
echo "$result:$workItem" >&$outputSyncPipeD; echo "$result:$workItem" >&$threadSyncPipeD;} &
((i++))
done
wait
echo "quit" >&$outputSyncPipeD
while read n; do
if [[ $n == "quit" ]]; then
break;
else
eval $6="\${$6}\ \$n"
fi
done <&$outputSyncPipeD;
}
main()
{
if [ ! -p threadSyncPipe ]; then
mkfifo threadSyncPipe
fi
if [ ! -p outputSyncPipe ]; then
mkfifo outputSyncPipe
fi
exec 4<>threadSyncPipe
exec 3<>outputSyncPipe
gout=
parallelizeTask "f1 f2 f3 f4 f5 f6" 2 mytask 3 4 gout
echo "finalOutput: $gout";
for f in $gout; do
echo $f
done
rm outputSyncPipe
rm threadSyncPipe
}
main
я нашел ниже, связанное сообщение с ответом на мой вопрос. Я пересмотрел название, чтобы сделать его более подходящим.
Are there repercussions to having many processes write to a single reader on a named pipe in posix?
Что вы пытаетесь сделать на простом английском языке? Ваш скрипт кажется сложным способом сделать что-то очень похожее на 'echo 'f1 \ nf2 \ nf3 \ nf4 \ nf5 \ nf6' | wargs -n1 -P2 mytask> подагра '. Или, может быть, я полностью ошибаюсь. – damienfrancois
Замечание по терминологии: 'bash' может запускать несколько процессов, а не потоков. Поток - это просто путь выполнения, который делится своей памятью с другими потоками в рамках одного процесса. – chepner
Вы проверяете и создаете 'threadSyncPipe' дважды; Я подозреваю, что второй раз вы имеете в виду 'outputSyncPipe'. – chepner