LINUX.ORG.RU

Вопрос про состояния процессов

 ,


1

1

Может ли быть у процесса такое состояние — сон до получения определённого сигнала? Если да, то как оно реализовано, ведь процесс спит, но в то же время готов принять сигнал? Или такого нет? Или сигналы проходят через планировщик? Или я чего-то не понимаю...

Как вообще в программах реализован приём сигналов?

Как на языке shell-scripting реализовать сон до получения определённого сигнала (на сколько я понимаю, с помощью kill -SIGUSR1)?

★★★★★

Довольно очевидно, что ядро тупо не начинает исполнять процесс до прихода сигнала.

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

а как это реализовано в самом процессе? ведь процесс ожидает определённый сигнал

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

так если сигстоп послать это остановлен будет, а не сон, разве нет?

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

Он ничего не ожидает, и вообще может не исполняться. Когда приходит сигнал, просто вызывается функция-обработчик, заданная через signal() или sigaction().

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

вызывается функция-обработчик, заданная через signal() или sigaction().

она вызывается из самого процесса?

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

Как ты себе такое представляешь?

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

вот я тебя и спрашиваю. тоесть это ядро вызывает функцию?

teod0r ★★★★★ ()

Думаю, что процесс переодически просыпается*, проверяет, не нужно ли что-либо сделать, и снова засыпает (говорит планировщику запустить след. процесс).
Как-то так:

while True:
    sleep(100)
    if check_smth():
        # do something
    else:
        # yeald to scheduler
* планировщик «будит»

Smola ()
Последнее исправление: Smola (всего исправлений: 1)
Ответ на: комментарий от teod0r

да, ядро, но в контексте процесса. теперь ты знаешь что нужно гуглить ;)

anonymous ()

Как на языке shell-scripting реализовать сон до получения определённого сигнала (на сколько я понимаю, с помощью kill -SIGUSR1)?

  trap 'kill ${P}' USR1

  while sleep 86400 & P=${!} ; wait ${P} ; do : ; done

Не вполне корректно (если сигнал придёт во время перезапуска sleep, он пропадёт), но если тебя это волнует, доработать, а также добавить определение того, каким именно сигналом прерван wait, несложно.

ABW ★★★★ ()

Сон (не путать с вытеснением планировщиком) начинается с вызова api, который, в конечном итоге, передает управление ядру, а то, в свою очередь, переставяет процесс из очереди исполняемых процессов в очередь ждущих (или в несколько очередей сразу).

Когда в ядре происходит событие, обрабатываемое в очереди ожидания, оттуда извлекается процесс и опять ставится в очередь исполнения. Также ему сигнализируется через флаги сигналов и/или результат упомянутой вначале api-функции.

German_1984 ★★ ()

Если ты хочешь, чтобы процесс спал, установи обработчик сигналов, которых ты ждешь, размаскируй эти сигналы, а затем выполни блокирующийся, но прерываемый системный вызов. Например, usleep(). Когда ядро получит сигнал для твоего процесса, и доставит сигнал до него, оно прервёт выполнение системного вызова. Процесс увидит это как выход из системного вызова с errno=EINTR.

А вообще для ожидания конкретно сигналов есть блокирующийся системный вызов sigwait().

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

Да, обработчик сигнала вызывается из самого процесса, которому пришёл сигнал. При этом механизм передачи сигналов реализован в ядре, поэтому состояние процесса может меняться при получении сигнала.

RTFM: man 7 signal

Если ты хочешь усыпить процесс именно до получения сигнала, то тебе поможет, например, man 3 sigwait. В баше используй built-in trap; аналогов sigwait там нету, поэтому можешь делать в цикле sleep 9999999.

tiandrey ★★★★★ ()
Последнее исправление: tiandrey (всего исправлений: 2)

Для сна до прихода сигнала из программы вызывают pause() или более продвинутая версия sigsuspend(), позволяющая избежать race condition.

Из кода просто вызывают эту функцию и она звершится по приходу сигнала. В каком именно внешнем состоянии (D, R, S, T, Z) будет процесс вам проще посмотреть самому, написав и скомпилив 10 строк.

Сигналы приходят через ядро, но не через планировщик. Ядро смотрит сигнальную маску процесса и, если сигнал принимается к обрабоке, изменяет стек процесса и адрес выполняемой иструкции, так что процесс начинает выполнять свой код обработчика сигнала. И, если процесс спал в ожидании сигнала его переводят в очередь активных задач, ожидающих когда планировщик запустит их.

На shell не вызвать sigsuspend(), пишут всякие костыли. Причём, ЕМНИП, trap это башизм. И работа с сигналами в bash'е получается кривая и не удобная...

mky ★★★★★ ()

SIGSTOP/SIGCONT

И пусть тебя не смущают всякие глупости. Эти сигналы они не процессу, а операционке.

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