URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5398
[ Назад ]

Исходное сообщение
"Зачистить концы после fork/exec - как?"

Отправлено vkozlov , 07-Май-06 12:17 
Помогите чайнику, переходящему с виндового программирования на линуксовое.
Использую Debian (не знаю, важно это или нет). Суть проблемы следующая:

имеется процесс, который в цикле читает данные с /dev/dsp, и если они превышают определенный порог, открывает на запись файл и пишет эти данные туда. После того, как некоторое время на /dev/dsp значение считываемых данных падает ниже указанного порога, файл закрывается и необходимо его скормить oggenc-у для перекодировки и компрессии из raw-sound в ogg.
Вот кусок исходника:

  for (;;) {
    read(mic,bufp,4);    
    val = ((int)data[0]+(int)data[2])+((int)data[1]+(int)data[3])*256;        
    if (abs(val) < thresh) {
       ...(здесь дампим /dev/dsp в файлик пока есть сигнал на входе саундкарты)             // запускаем перекодировщик отдельным процессом чтоб не мешал следующей записи
       pid_t pID;
       pID = fork();
       if (pID==0) {
         execlp("sh","-c","runogg.sh",recfile2,NULL);
       }
    }        
  }

И вот содержимое runogg.sh:

oggenc --raw -B 16 -C 2 -R 44100 --quiet $1 > /dev/null
rm $1
exit

Проблема в том, что после каждого запуска энкодера в системе остается "потерянный" child-процесс, который бы согласно правилам хорошего тона надо убрать. В винде это называлось незакрытым хэндлом, и там я просто пускал поток, в потоке запускал процесс, ждал когда он завершится (при этом основной процесс записи raw-звука продолжает работать, пишет файлы и запускает потоки с запуском энкодера для каждого нового файла) и после завершения процесса прибивал хэндлы процесса и запущенного для его инициализации потока.
Вопрос: как в линухе это правильно сделать?


Содержание

Сообщения в этом обсуждении
"Зачистить концы после fork/exec - как?"
Отправлено chip , 07-Май-06 14:20 

>Вопрос: как в линухе это правильно сделать?


man 2 wait
man 2 waitpid


"Зачистить концы после fork/exec - как?"
Отправлено vkozlov , 07-Май-06 14:26 
>man 2 wait
>man 2 waitpid

И пускать fork/exec внутри отдельного треда, чтоб вайты основному демону не мешали, насколько я понимаю?

Если вопрос чайниковский ногами не бейте, под винду я пишу давно и много, а пингвина всего неделю дрессирую :)



"Зачистить концы после fork/exec - как?"
Отправлено guest , 07-Май-06 15:05 
>>man 2 wait
>>man 2 waitpid
>
>И пускать fork/exec внутри отдельного треда, чтоб вайты основному демону не мешали,
>насколько я понимаю?
>

зачем создавать поток ради этой задачи/не-задачи. у wait/waitpid есть замечательная опция WNOHANG.


"Зачистить концы после fork/exec - как?"
Отправлено chip , 07-Май-06 15:57 
>>man 2 wait
>>man 2 waitpid
>
>И пускать fork/exec внутри отдельного треда, чтоб вайты основному демону не мешали,
>насколько я понимаю?
>
>Если вопрос чайниковский ногами не бейте, под винду я пишу давно и
>много, а пингвина всего неделю дрессирую :)

http://www.opennet.me/search.shtml

Тема поднимается как минимум раз в 2-а месяца.



"Зачистить концы после fork/exec - как?"
Отправлено vkozlov , 07-Май-06 16:02 
>Тема поднимается как минимум раз в 2-а месяца.

Тема поднимается, но и ряды чайников типа меня постоянно пополняются... чтение гугля на тему waitpid/whohang/zombie ни к чему путному не привело... ткните меня пожалуйста мордой (или чайниковым носом) в пример _работающего_ вызова sh-скрипта не порождающего зомби.

А я в благодарность за вас пива выпью :)



"Зачистить концы после fork/exec - как?"
Отправлено guest , 07-Май-06 23:07 
>>Тема поднимается как минимум раз в 2-а месяца.
>
>Тема поднимается, но и ряды чайников типа меня постоянно пополняются... чтение гугля
>на тему waitpid/whohang/zombie ни к чему путному не привело...

а `info libc' слабо почитать? на тему процессов, а лучше весь целиком. или во фре сидишь? посмотри тогда online версию мануала glibc.
Лично я именно по этому мануалу и изучать программирование в *nix. не задавая глупых вопросов, не ползая по гуглю в поисках факов, туторов и примеров, и не покупая глупых книжек.


"Зачистить концы после fork/exec - как?"
Отправлено vkozlov , 08-Май-06 09:45 
>а `info libc' слабо почитать? на тему процессов, а лучше весь целиком.
>или во фре сидишь? посмотри тогда online версию мануала glibc.
>Лично я именно по этому мануалу и изучать программирование в *nix. не
>задавая глупых вопросов, не ползая по гуглю в поисках факов, туторов
>и примеров, и не покупая глупых книжек.

Надыбал вчера книжку - Marc Rochkind "Advanced UNIX Programming", книжка оказалась довольно-таки неглупой, и методы борьбы с зомби там в главе посвященной процессам хорошо растолкованы.

Так что решение проблемы я нашел: учитывая что в моей задаче после длинной сессии записи может следовать несколько коротких, и они запустят энкодер в момент когда энкодер инициированный длинной сессией еще не завершился, нужно в главном процессе создать пул child-ов и waitpid-ом по нему перед запуском каждой новой сессии пробегать. Тогда новая сессия будет прибивать старые зомби и накопления зомбиков не будет.