Смотрите здесь
Есть два сигнала, которые могут приостановить выполнение процесса. Один "грациозен", а другой "силен".
"Изящным" является SIGTSTP
, и его цель - "приятно" спросить процесс, если он чувствует себя так, как нужно, пожалуйста приостановить выполнение, пока не получит SIGCONT
. В случае SIGTSTP
процесс может игнорировать SIGTSTP и продолжать выполнение в любом случае, поэтому для этого требуется сотрудничество со стороны программы, которая предназначена для обработки SIGTSTP.
"Принудительным" является SIGSTOP
, и его целью является приостановка всех потоков пользовательского пространства, связанных с этим процессом. Для процесса так же невозможно игнорировать SIGSTOP
как и для него игнорировать SIGKILL
(последний принудительно убивает процесс).
Чтобы отправить произвольный сигнал, в том числе любой из упомянутых здесь, вы можете использовать такие программы, как kill
, killall
или pkill
; или используйте системный вызов kill(2)
. Обратитесь к руководствам вашей операционной системы, чтобы узнать подробности, связанные с платформой / архитектурой / версией, а также сведения об ошибках, связанных с любым из вышеперечисленных. Обратите внимание, что слово "kill" во всех этих командах и системном вызове - это неправильное название. Эти команды не предназначены исключительно для завершения процессов. Они могут сделать это, отправив определенные сигналы; но сигналы могут также использоваться для функциональности, отличной от завершения процесса. Например, SIGSTOP
только приостанавливает процесс, и это только один из нескольких сигналов, которые могут быть отправлены таким образом.
Чтобы добавить условие автоматического возобновления процесса по истечении определенного периода времени, вам нужно будет использовать какой-то процесс мониторинга, который остается запущенным и устанавливает таймер для запуска процесса мониторинга, который затем вызывает kill(2)
снова и отправляет сигнал SIGCONT
остановленному процессу, чтобы запросить ядро возобновить выполнение. Обратите внимание, что в Linux есть несколько механизмов синхронизации с различной степенью точности; Более того, если ваша система очень занята, ваш процесс мониторинга может не проснуться до тех пор, пока не истечет его таймер, и, следовательно, пробуждение может быть отложено.
Если вы зависите от очень точной точности приостановки и возобновления приостановленного процесса, вам может потребоваться запустить программу мониторинга с разрешениями в режиме реального времени (см. Эту справочную страницу на sched_setscheduler(2)
для получения информации о том, как сделать процесс в реальном времени). Вы также можете использовать таймеры высокого разрешения, функцию ядра Linux (которая доступна только в том случае, если ваше оборудование обеспечивает их поддержку), в сочетании с планированием в реальном времени, чтобы получить очень точную точность с точностью до миллисекунды, а затем включите и отправьте сигнал для возобновления отслеживаемого процесса очень быстро.
Вы не указали, какие технологии вы хотите использовать для реализации этого. Как минимум, вам понадобится, по крайней мере, сценарий bash, хотя вы не сможете получить очень точную синхронизацию таким образом. Вот bash-скрипт (непроверенный, поэтому, пожалуйста, будьте осторожны), который является просто доказательством концепции вашего запроса. Если вам нужно точное время, вам нужно написать программу, вероятно, на C/C++ или другом родном языке, и использовать планирование в реальном времени и hrtimers.
#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"
Обратите внимание, что сценарий завершится, а управляющий сценарий завершится, но из-за того, что screen
контролирует процесс монитора, он продолжит работу в фоновом режиме в течение 10 секунд (на основе аргумента, переданного в sleep
), а затем проснется и продолжит дочерний процесс , Но это будет долго после того, как управляющий скрипт закончится. Если вы хотите синхронно ждать истечения времени, просто пропустите второй вызов screen
и жестко закодируйте сон и уничтожьте его в управляющем скрипте.
Вы можете проверить, что процесс на самом деле приостанавливается, запустив
screen -rS child
после запуска этого скрипта. Вы не увидите ничего на консоли. Затем, после истечения таймера (10 секунд), он заполнит ваш экран данными base64 (случайные символы от 0 до 9 и AF). Нажмите Ctrl+C, чтобы выйти.