Есть ли способ приостановить запущенный процесс в системах Linux и возобновить его позже?

38

Я должен копировать файлы на машине. И данные очень велики. Теперь серверы должны работать в обычном режиме, и на них обычно есть определенный диапазон часов работы. Так есть ли способ выполнить такие команды таким образом, что если сервер попадает в часы занятости, он приостанавливает процесс, а когда выходит из этого диапазона, возобновляет его?

Предназначенный-Result

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.
Sollosa
источник
22
rsync может возобновить частичные переводы
Торбьерн Равн Андерсен
2
Вам нужно скопировать фактические данные в качестве резервной копии? Если нет, то не могли бы вы использовать cp -alферму с жесткими ссылками? Или использовать файловую систему, которая поддерживает ссылки на уровне блоков с копированием при записи, используя cp -a --reflink=auto? BTRFS и ZFS поддерживают это для копий в пределах одного физического устройства.
Питер Кордес
9
Изменяются ли какие-либо файлы srcс 9:00 до 14:00? Если это так, простая приостановка и возобновление cpпроцесса может привести к повреждению файлов. Может быть, лучше запустить rsyncв сочетании с timeoutкомандой.
Марк Плотник
Откуда и куда копируются файлы? Это виртуальная система? Что такое исходная файловая система? Какова цель копии?
Брайам
@Braiam Я использую rsync и копирую файлы с удаленного компьютера на локальный. Я просто использовал команду cp в качестве примера здесь
Соллоза

Ответы:

8

Да нужно

acquire the process id of the process-to-paus (PS), then do
$> kill -SIGSTOP <pid>

Затем процесс отобразится со статусом «T» (PS). Чтобы продолжить делать

$> kill -CONT <pid>

Удачи!

герхард д.
источник
77

Вы можете приостановить выполнение процесса, отправив ему сигнал SIGSTOP, а затем возобновить его, отправив сигнал SIGCONT.

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

# start copy in background, store pid
cp src dst &
echo "$!" >/var/run/bigcopy.pid

Затем, когда начинается занятое время, отправьте SIGSTOP:

# pause execution of bigcopy
kill -STOP "$(cat /var/run/bigcopy.pid)"

Позже, когда сервер снова простаивает, возобновите его.

# resume execution of bigcopy
kill -CONT "$(cat /var/run/bigcopy.pid)"

Вам нужно будет запланировать это на определенное время, когда вы хотите, чтобы оно выполнялось, вы можете использовать такие инструменты, как таймеры cron или systemd (или множество других подобных инструментов), чтобы получить это расписание. Вместо планирования на основе временного интервала вы можете контролировать сервер (возможно, просматривая среднюю нагрузку, использование процессора или активность из журналов сервера), чтобы принять решение о том, когда следует приостановить / возобновить копирование.

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

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

filbranden
источник
7
+1 Смотрите также utcc.utoronto.ca/~cks/space/blog/unix/SIGSTOPUsesAndCautions
епископ
1
Возможно, добавьте напоминание о том, что вы должны быть очень осторожны, так как «/var/run/bigcopy.pid» по-прежнему ссылается на тот же процесс, что и вы думаете. случайная остановка других процессов в системе может быть нежелательной. Я не знаю ни одного безопасного способа гарантировать, что pid ссылается на программу, которую, как вы думаете, он делает ...
Эван Бенн
@EvanBenn Да, это то, что я имел в виду в смысле «убедитесь, что ваша копия на самом деле все еще работает, прежде чем приостановить ее», хотя ваша точка зрения, безусловно, более ясна, чем это! Да, проверка PID по своей сути является гонкой, поэтому иногда на самом деле невозможно сделать это на 100% надежно ...
filbranden
@cat Не совсем, процесс не может заблокировать SIGSTOP. См. Ссылку из первого комментария: «SIGSTOP - это неблокируемый сигнал, такой как SIGKILL» (или просто Google, вы увидите, что это так.)
filbranden
76

Вместо того, чтобы приостанавливать процесс, вы также можете придать ему более низкий приоритет:

renice 19 "$pid"

придаст ему наименьший приоритет (наивысшую точность), чтобы процесс уступал ЦП другим процессам, которые в большинстве случаев нуждаются в нем.

В Linux то же самое можно сделать с помощью ввода / вывода с помощью ionice:

ionice -c idle -p "$pid"

Поместит процесс в класс «бездействия», чтобы он получал время на диске только тогда, когда ни одна другая программа не запрашивала дисковый ввод-вывод в течение определенного льготного периода .

Стефан Шазелас
источник
22
Это типичный случай проблемы XY . Вопрос был в том, как приостановить процесс, но это не отвечает на вопрос. Действительно, снижение приоритета - лучший подход к актуальной проблеме, но он не отвечает на вопрос. Я бы отредактировал вопрос, включив в него также, как приостановить процесс и почему может возникнуть проблема с приостановкой (например, файл может быть отредактирован во время приостановки).
MechMK1
22
@DavidStockinger, технически, этот ответ рассказывает, как сказать ОС приостановить процесс, когда она (ОС, ЦП, планировщик ввода-вывода) занята (даже если это на доли секунды за раз). Как приостановить процесс вручную уже было рассмотрено в других ответах. Это решение не решает проблему изменения файлов во время их копирования.
Стефан Шазелас
5
Изменение приоритета ввода / вывода не всегда является лучшим решением. Если вы копируете с вращающихся дисков, вы все равно можете выполнять поиск перед каждым высокоприоритетным запросом, который не возник бы, если бы вы полностью приостановили операцию с низким приоритетом.
Марк
2
Низкий приоритет даже не решает проблему. Даже если ящик полностью простаивает в течение нескольких секунд или минут, это не означает, что процесс копирования, который будет удалять все из кэша файловой системы, будет ненавязчивым. Как только снова появится нагрузка, она будет очень медленно перелистывать все обратно.
R ..
2
@DavidStockinger предпочтительный способ решения проблем XY - дать правильное решение, даже если вопрос не в этом. Когда вы знаете, что подход, описанный в вопросе, неверен, тогда хороший ответ не дает этого неправильного подхода, а предлагает лучший.
тердон
8

Используйте rsync, забудьте про cp для этого сценария. Есть параметры для ограничения полосы пропускания, или они могут быть убиты / остановлены и запущены позже, таким образом, это будет продолжаться, где он оставил google rsync example / s

Антон Томанек
источник
3

Если вы собираетесь сделать это, прервав запущенный процесс, я предлагаю поиграть с программой Screen. Некоторое время я не пользовался Linux, но IIRC, просто приостановив команду и возобновив ее позже, оставляет вас довольно уязвимыми, если вы случайно выйдете из системы, вы не сможете возобновить сеанс.

С экраном я думаю, что вы можете прервать сеанс, затем отсоединить его и выйти из системы. Позже вы можете вернуться и снова присоединиться к этому сеансу. Вы должны немного поиграть с ним, но это сделало сессии намного более надежными.

Вы также можете выйти из системы и вернуться домой, затем войти удаленно, подключиться к системе, которую вы запустили в офисе, и возобновить ее на вечер, а затем снова забрать на следующий день на работе.

Билл К
источник
Я уже использую Tmux для этого. Но я пишу сценарий, который был бы самосознающим или предпочтительно окружающим, поэтому он останавливается, если сервер получает высокий трафик, и продолжает, когда это нормально.
Соллоза
0

Если ваша оболочка поддерживает это (почти все), вы можете нажать ^ Z (Ctrl + Z), чтобы легко отправить SIGTSTPсигнал на задание переднего плана, а затем продолжить его с fg(на переднем плане) или bg(на заднем плане).

Если вы делаете это для нескольких задач и хотите вернуться к ним позже, вы можете использовать jobsкоманду, а затем вернуться с помощью fg/bg %#, где # - это число, указанное в скобках для заданий.

Имейте в виду, что SIGTSTPэто немного отличается от SIGSTOP(который используется во всех других ответах), что наиболее важно из-за того, что его можно игнорировать (но я не видел, чтобы программа игнорировала его, кроме sl). Более подробную информацию можно найти в этом ответе на StackOverflow .

Ave
источник
Удивлен, что ни один ответ не упомянул это еще.
пр
Тай Аве, я знаю этот многозадачный трюк. Но для того, чтобы это произошло, нужно быть на терминале, тогда как я должен был создать скрипт, который будет выполнять работу самостоятельно, независимо от того, займет ли это дни.
Соллоза
@Sollosa может быть полезна другим с таким же вопросом и с доступом к терминалу.
пр
Я согласен.
Хорошо,