LINUX.ORG.RU

Вопросы про фоновые процессы


0

1

1. Какая разница между демоном и фоновым процессом (т.е. то, что в sh запускается с амперсандом)?

2. Имеется скрипт

#!/bin/sh
prog &
Когда скрипт завершиться, prog останется в памяти? Если нет, то prog получит от sh сигнал SIGTERM? Или как? Есть ли раличия относительно этого поведения в sh и bash?


1. У фонового процесса остаются открытыми файловые дескрипторы stdout и stderr, а также его при определённых условиях может прибить SIGHUP, полученный вследствие закрытия окна терминала, с которого была введена команда.
2. Да, останется. Нет, различий нет.

AITap ★★★★★ ()
Ответ на: комментарий от AITap

2. Да, останется.

Запустил терминал (с bash'ем). Ввёл в нём «htop &». Проверил, что процесс в памяти: так и есть. Вышел из терминала. В другом терминале проверил процесс htop: его нет. Что я не так делаю?

toady2 ()
Ответ на: комментарий от toady2

> Вышел из терминала.
htop прибило SIGHUP'ом. Нужно было использовать nohup, detach либо выходить из bash при помощи команды exit.

AITap ★★★★★ ()

>Какая разница между демоном и фоновым процессом (т.е. то, что в sh запускается с амперсандом)?

Демон создает новую сессию (setsid) и отключается от терминала.

AptGet ★★★ ()

В таком случае вопрос: можно ли считать скрипт, запускаемый из /etc/rc.local командой /usr/scripts/scriptname & демоном? Он у меня висит себе и работает, проверяет параметры питания каждые 10 секунд и есть не просит.

Othniel ()
Ответ на: комментарий от tailgunner

Это ответы на твои вопросы %)

-- 1. Какая разница между демоном и фоновым процессом (т.е. то, что в sh запускается с амперсандом)?

-- Да, нет, просто ничего не произойдет, нет.

toady2 ()
Ответ на: комментарий от AITap

htop прибило SIGHUP'ом.

А, так значит всё же закрывающийся шелл отправляет всем подпроцессам SIGHUP? Но ведь дефолтно SIGHUP и обрабатывается как убийство.

либо выходить из bash при помощи команды exit.

Проверил сейчас. Такой же результат, как с Ctrl-D.

P.S. Конец скрипта для исполняющего шелла интерпретируется как Ctrl-D. Так ведь?

toady2 ()

Вопрос 3. Пусть есть программа, которая не ставит своих обработчиков сигнала. Тут её поступает SIGTERM (или SIGHUP, или SIGUSR1... ведь дефолтно они все одно означают?): программа убьётся. Но как? Насколько корректно такое завершение? Если программа имеет вид типа

open_file blabla
create_file bububu
while (true) { do_something; }
remove bububu
close blabla
То удалится ли при убийстве bububu и закроется ли blabla?

toady2 ()
Ответ на: комментарий от toady2

> — 1. Какая разница между демоном и фоновым процессом (т.е. то, что в sh запускается с амперсандом)?

Очевидно, что это ответы на пункт 2 %) Под «демоном» можно понимать разное - от просто команды, запущенной в фоновом режиме, до системной службы с setsid, chdir(«/»), закрытыми потоками и корректной остановкой по сигналам. Ты о чем срашивал?

tailgunner ★★★★★ ()
Ответ на: комментарий от toady2

Не удалится, закроется.

Чтобы ненужный файл «автоудалялся», сразу после его создания надо стелать unlink:

open_file blabla;
create_file bububu;
unlink(bubuntu);
while (true) { do_something; }
remove bububu;
close blabla;

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от tailgunner

до системной службы с setsid, chdir(«/»), закрытыми потоками и корректной остановкой по сигналам.

Да, под демоном я имел это. Под фоновым процессом программу, запускающуюся в шелле с приставкой &.

А зачем нужен setsid?

Пусть фон. программа обрабатывает сигналы, не пишет и не читает из стандартных потоков. Есть ли какое-нибудь принципиальное различие между демоном и фон. процессом в шелле?

Пусть мне нужно каждые 10 минут что-нибудь делать (пускай, мигнуть светодиодом). Есть ли приемущество сделать эту программу демоном нежели просто запустить в стартовых скриптах с амперсандом?

toady2 ()
Ответ на: комментарий от toady2

Мало только SIGHUP обрабатывать. Надо еще, как было сказано выше, позакрывать все открытые файловые дескрипторы (т.е., если никаких файлов не открывали, сделать close(0); close(1); close(2)) и открыть новую сессию (fork()).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Я правильно понимаю, что когда процессу даётся убивающий сигнал (который он не обрабатывает), то его просто насильно убивают на той команде, которая исполняется в данный момент? То есть убийство получается некорректным?

toady2 ()
Ответ на: комментарий от toady2

Правильно. Поэтому сигналы надо обрабатывать. Тот же SIGTERM вы можете перехватить и до завершения программы выполнить какие-то действия (сбросить буферы, отключить питание чего-либо, отключить разделяемые области памяти и т.п.). А вот SIGKILL перехватить нельзя, и по kill -9 ваша программа будет некорректно завершена.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от toady2

> А зачем нужен setsid?

Если на пальцах, то Чтобы не поймать SIGHUP. Если техническим языком... надо вспоминать, что такое session leader, а мне влом :)

Пусть фон. программа обрабатывает сигналы, не пишет и не читает из стандартных потоков. Есть ли какое-нибудь принципиальное различие между демоном и фон. процессом в шелле?

Смотря что для тебя является принципиальным.

Пусть мне нужно каждые 10 минут что-нибудь делать (пускай, мигнуть светодиодом). Есть ли приемущество сделать эту программу демоном нежели просто запустить в стартовых скриптах с амперсандом?

На мой взгляд, нет.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Если на пальцах, то Чтобы не поймать SIGHUP.

То есть если выполнить setsid, завершающийся шелл не отправит HUP этому процессу?

toady2 ()
Ответ на: комментарий от Eddy_Em

Тот же SIGTERM вы можете перехватить и до завершения программы выполнить какие-то действия (сбросить буферы, отключить питание чего-либо, отключить разделяемые области памяти и т.п.)

и по kill -9 ваша программа будет некорректно завершена.

Спасибо. Кажись понял то, что так долго хотел понять. То бишь по дефолту почти все сигналы (если их не обрабатывает программа) работают как SIGKILL, то есть просто тупо убивают исполнение процесса в том месте, на котором она сейчас находится.

Теперь даже в не-демонах буду всегда перехватывать TERM, HUP, INT.

toady2 ()
Ответ на: комментарий от toady2

> То есть если выполнить setsid, завершающийся шелл не отправит HUP этому процессу?

SIGHUP отправляется ядром, а не шеллом, при закрытии управляющего терминала процесса. У свежего session leader'а нет управляющего терминала, так что ему SIGHUP не отправляется.

tailgunner ★★★★★ ()
Ответ на: комментарий от toady2

Можно еще проще сделать:

for(int  _=0; _<255; _++) signal(_, stop);
А в функции-обработчике выполнять определенные действия в зависимости от сигнала, например:
void stop(int sig){
        int i;
        fprintf(logfile, "Caught signal: %d\n", sig);
        if(sig == SIGINT || sig == SIGQUIT || sig == SIGABRT){
                shmctl(shmid, IPC_RMID, NULL); // удаляем сегмент *Nbuf_cur
                pthread_kill(thread, 9);
                stop_all_devices();
                fclose(logfile);
                if(out_buf && sig != SIGABRT) free(out_buf);
                for(i=0; i<4; i++){
                        snprintf(shmname, 31, "/shm%d", i);
                        shm_unlink(shmname);
                }
                rm_queues();
                exit(0);
        }
        else signal(sig, stop); // все остальные сигналы игнорируем
}

Eddy_Em ☆☆☆☆☆ ()

Вот конкретный пример: программа dwmstatus, которая в цикле (со sleep'ом на минуту) устанавливает статусбар window-manager'а (напр. dwm). При этом один из сигналов (напр. SIGUSR1) перехватывается и вызывает насильное обновление статусбара.

Как лучше делать и какие важные отличия, которые следует учесть, в двух вариантах:

1) dwmstatus является демоном. .xinitrc:

dwmstatus
dwm
killall dwmstatus

2) dwmstatus обычная программа, корректно завершаюяся по SIGHUP. .xinitrc:

dwmstatus &
exec dwm

toady2 ()
Ответ на: комментарий от toady2

Это плохой пример. Вместо signal() нужно sigaction() с маскировкой других сигналов в обработчике. Операции ввода/вывода в обработчике сигнала зло как и игнорирование SIGSEGV.

mky ★★★★★ ()

Я верно понимаю, что отличие ещё в том, что демон вызывает fork, чтобы отречься от родителя, который запущен в шелле; а фоновую программу шелл «сразу» запускает в фоне? Если да, то что выгодней с точки зрения траты системных ресурсов и времени: запустить демон или фоновую программу?

toady2 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.