Почему-то не нашел примеров использования именованных каналов для синхронизации процессов. С их помощью можно легко написать скрипт для распараллеливания задач - просто на bash (например, для кодирования видео или архивации большого кол-ва файлов в несколько потоков, чтобы использовать все имеющиеся в наличии ядра CPU)!
В демонстрационных целях распараллеливать буду очередь из 10 команд sleep <случайное число> :))
Подробная информация об именованных каналах в UNIX:
http://developers.sun.com/solaris/articles/named_pipes.html
Особенно рекомендуется 10 строк раздела "Reading From and Writing to a Named Pipe"
Там содержатся основные замечания, которые надо иметь ввиду, используя named pipes для синхронизации.
В демонстрационных целях распараллеливать буду очередь из 10 команд sleep <случайное число> :))
#!/bin/bash PipeFile="./task4all.pipe" LogFile="./task4all.log" MaxParallelTasks=3 TaskList=$(for i in {1..10} ; do echo $((RANDOM%12)) ; done); ParallelTasks=0 #Проверяем, нет ли уже созданного именованного канала, если нет - создаем [ -p $PipeFile ] || mkfifo $PipeFile #Основной цикл по задачам for task in $TaskList ; do #Если максимальное число потоков достигнуто - ждем завершения одного или нескольких #из работающих процессов (или просто читаем сообщения о завершении работы, #которые могли накопиться в канале). if [ $ParallelTasks -eq $MaxParallelTasks ] ; then taskscompleted=$(wc -l $PipeFile | cut -d' ' -f 1) ParallelTasks=$(($ParallelTasks-$taskscompleted)) fi #Увеличиваем число работающих потоков на 1 и стартуем работу в новом экземпляре shell. #По завершении работы, порожденный shell запишет сообщение об этом в именованный канал #и дождется прочтения этого сообщения родительским скриптом. ((ParallelTasks++)) echo "start:$(date +%d%m%Y.%H%M%S):$task" >> $LogFile && sleep $task && echo "finish:$(date +%d%m%Y.%H%M%S):$task" | tee -a $PipeFile >> $LogFile & done echo "$(date +%d%m%Y.%H%M%S):All tasks started!" | tee -a $LogFile #Ждем завершения последних рабочих процессов while [ ! $(grep -c 'start:' $LogFile) -eq $(grep -c 'finish:' $LogFile) ] ; do cat ./task4all.pipe > /dev/null done echo "$(date +%d%m%Y.%H%M%S):All tasks finished!" | tee -a $LogFile #Удаляем канал rm $PipeFile
Подробная информация об именованных каналах в UNIX:
http://developers.sun.com/solaris/articles/named_pipes.html
Особенно рекомендуется 10 строк раздела "Reading From and Writing to a Named Pipe"
Там содержатся основные замечания, которые надо иметь ввиду, используя named pipes для синхронизации.