Может ли процесс работать в фоновом режиме?

Чтобы разрешить bytenr , используйте следующую команду:

btrfs inspect-internal logical-resolve  

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

Пример:

mkdir /mnt/btrfs-root
mount -t btrfs -o subvolid=5 /dev/sda2 /mnt/btrfs-root

btrfs inspect-internal logical-resolve 1337316519936 /mnt/btrfs-root

umount /mnt/btrfs-root && rmdir /mnt/btrfs-root

Обратите внимание, что:subvolid=5будет монтировать «корневой раздел BTRFS» (или субтом верхнего -уровня ). Только что созданная файловая система также является подтомом, называемым верхним -уровнем, имеющим внутренний идентификатор 5.(Kernel.org)

3
29.08.2020, 10:10
2 ответа

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

Первое замечание по терминологии.

Фоновый режим обычно относится к управлению заданиями в интерактивных оболочках.

Например, когда вы запускаете команду с добавленным &. Или нажмите Ctrl + Z и затем запустите bg.

Задания не процессы, а группы процессов . Когда вы бежите:

$ ps -ej | grep -w "$$" & echo "$!"
35131
  19152   19152   19152 pts/0    00:00:00 zsh
  35130   35130   19152 pts/0    00:00:00 ps
  35131   35130   19152 pts/0    00:00:00 grep

Этоps | grepзадание (, реализованное здесь через группу процессов 35130, лидером которой является запущенный процесс ps, но также содержит запущенный процесс grep), переведенный в фоновый режим.

Фон здесь означает:

  1. Оболочка не ожидает завершения этого задания. Вы вернетесь к подсказке и сможете вводить дополнительные команды, пока это задание все еще выполняется.
  2. Драйвер терминального устройства сообщает, что эта группа процессов не находится на переднем плане. Таким образом, процессы в этой группе процессов не имеют права читать с терминала (все процессы в группе будут прерваны, если какой-либо процесс в ней попытается прочитать с терминала )и не получит затронуты ^C/ ^Z/ ^\и т. д.
  3. Оболочка вводит задание в свою внутреннюю таблицу заданий и записывает его как находящееся в фоновом режиме.

Теперь формулировка фонового иногда используется за пределами управления терминальными заданиями.

Когда вы делаете:

cmd1 | cmd2 & pid=$!
somecommand
wait

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

, но это cmd1 | cmd2в сценарии не будет переведено в фоновый режим оболочкой, интерпретирующей сценарий как не интерактивную оболочку.

Если вы нажмете ^C, cmd1и cmd2будут точно так же уничтожены вместе с оболочкой, выполняющей скрипт, и приостановлены, когда вы нажмете ^Z. Вместо того, чтобы говорить, что cmd1 | cmd2запускается в фоновом режиме, правильнее сказать, что они запускаются асинхронно .

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

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

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

  • Я в сеансе, подключенном к терминалу? (Имеет ли вообще смысл управление заданиями?)
  • Я один в своей группе процессов или есть другие процессы?
  • моя группа процессов уже находится в активном или фоновом режиме?
  • Ожидается ли моя группа процессов интерактивной оболочкой?

Если мы можем ответить «да» на все эти вопросы, то есть если нас вызывают как простую команду (, а не как часть конвейера или составную команду )из интерактивной оболочки в терминале, тогда нам потребуется to (1 )сообщить ожидающей оболочке, чтобы она прекратила нас ждать, (2 )сообщить терминалу, что его группа процессов больше не является приоритетной, и (3 )сообщить оболочке, чтобы обновите свою таблицу заданий, чтобы записать тот факт, что мы сейчас в фоновом режиме.

На самом деле вы не можете сказать другому процессу прекратить ждать вас, кроме как путем завершения или приостановки, и в этом случае этот процесс получит сигнал SIGCHLDили вызов wait*(), который он выполняет в настоящее время, вернется.

Тем не менее, вы можете приостановить себя, отправив себе сигнал SIGTSTP (, который отправляется при нажатии^Z)или SIGSTOP (, который не может быть перехвачен ), и в этом случае все (1 ), (2 )и (3 )произойдет автоматически, за исключением того, что состояние задания будет приостановлено вместо работающее в фоновом режиме .

Теперь, поскольку вы отстранены, вы больше не работаете и не можете возобновить свою работу.

Однако вы можете разветвить дочерний процесс, который возобновит работу самостоятельно (, отправив SIGCONT на ваш pid )за некоторое время до приостановки.

Когда вы возобновите выполнение, ваша оболочка снова получит SIGCHLD,и (3 ), когда оболочка понимает, что вы сейчас работаете в фоновом режиме, произойдет, когда она обработает этот сигнал.

В качестве примера, реализуя это вsh:

$ sh -c 'echo running in foreground; sleep 1
         (sleep 1; echo resuming my parent; kill -s CONT "$$") &
         echo stopping; kill -s STOP "$$"
         echo resumed
         sleep 30
         echo finished'; echo "$?"
running in foreground
stopping
147
zsh: suspended (signal)  sh -c
$ resuming my parent
resumed
$ jobs
[1]  + running    sh -c
$ finished
[1]  + done       sh -c

Также можно приостановить всю вашу работу с помощьюkill(0, SIGSTOP)(kill -s STOP 0в sh), но правильно ли, чтобы процесс делал это, чтобы повлиять на поток выполнения процессов, которые он не запускал и о которых не знает? ?

sh -c 'echo running in foreground
       perl -MPOSIX -le "setpgid 0,0; # leave the process group before it is suspended
                         sleep 2;
                         print q(resuming the process group of my parent);
                         kill q(CONT), - shift@ARGV
                        " "$(ps -o pgid= -p "$$")" &
       sleep 1
       echo stopping my process group; kill -s STOP 0
       echo process group resumed
       sleep 30
       echo finished' | cat
6
18.03.2021, 23:09

Только иногда.

  • Процесс, работающий в фоновом режиме, имеет идентификатор группы процессов, который отличается от текущего идентификатора группы процессов переднего плана на управляющем терминале.
  • Это не следует путать с процессом, который работает как демон , который выполняется вне всех сеансов входа в систему, где понятия переднего плана и фона просто не применяйте , потому что в первую очередь нет управляющего терминала.

Совет в ответе Анхеля устарел и плох. «демонизация», как ее называют, на самом деле не работает из сеансов входа в систему. Существует слишком много -лазеек, через которые проходят системы, чтобы настроить сеансы входа в систему; и не только ответ Анхеля игнорирует такие вещи, как OpenBSD setlogin(), защищенную среду AIX (, см. setsenv), а также контексты безопасности и группы управления Linux, старая библиотека daemon()также работает почти во всех библиотеках C.

Это не работает с 1980-х годов; потому что в 1990-х появилось много таких лазеек с одним -путем. «демонизация» — это заблуждение, к сожалению, все эти годы спустя все еще поддерживаемое общепринятой мудростью и фольклором.

Дело даже не в том, что демоны должны делать. Подсистемы управления услугами конца 1980-х (, например. AT&T Unix Service Access Facility )и 1990-е годы (, например. Контроллер системных ресурсов IBM )и далее вызывает демонов уже в контексте демона . Во-первых, они не запускаются в контексте сеанса входа в систему.

Кроме того, выполнение fork -и -выхода -приводит к конфликту с родительской семантикой, которую подсистемы управления службами использовали для демонов более 3 десятилетий; а закрытие файловых дескрипторов конфликтует с механизмами ведения журнала, которые подсистемы управления службами настроили для демонов.

  • Закрытие файловых дескрипторов не связано с сигналами TTY (это пример фольклора, о котором я упоминал ранее ), и он опровергает то, как подсистемы управления службами от daemontools через systemd до runit настраивают стандартный вывод и стандартную ошибку для отправить в лог. Подсистемы управления службами не запускают демоны с открытыми произвольными файловыми дескрипторами; они начинают их с воспроизводимого и согласованного и обычно минимального (, если явно не настроено иное ), набор дескрипторов открытых файлов.
  • Разветвление и выход из родителя — это вещь 1980-х годов, когда системные администраторы запускали демонов, добавляя их в сценарии оболочки /etc/rcили /etc/rc.localили даже в интерактивном режиме из сеанса входа в систему суперпользователя, и отрицали тот факт, что подсистемы управления службами использовать идентификатор процесса, полученный от fork()процесса службы, для отслеживания и управления службой. (Как видно из дальнейшего чтения, IBM советует не делать этого почти столько же, сколько существует ее Контроллер системных ресурсов. )Подсистемы управления службами вызывают демонов в сеансах, которые уже не имеют управляющего терминала.

Более того, «демонизация» — это не то, что нужно сделать, чтобы работать в фоновом режиме во время сеанса входа в систему . Оболочка «управление заданием -» переводит вещи на передний и задний план в сеансах входа в систему, вызывая функцию tcsetpgrp()для изменения текущего значения идентификатора группы процессов переднего плана управляющего терминала. На самом деле это не имеет ничего общего с fork(), chdir(), закрытием файловых дескрипторов или (сеансами ядра ).

Дочерний процесс оболочки может вызывать tcsetpgrp(), но обратите внимание, что (a )ему будет отправлен сигнал SIGTTOU, если он уже в фоновом режиме, и (b )непросто -найти другой идентификатор группы процессов для переключения,поскольку оболочка не может быть непосредственным родительским процессом во всех обстоятельствах.

  • Если вы хотите запустить процесс в фоновом режиме, используйте для этого &механизм оболочки.
  • Если вы хотите интерактивно переключить группу процессов переднего плана в фоновый режим, отправьте с терминала специальный символ «стоп».
  • Если вы хотите запустить что-то в качестве демона, не связанного с передним и фоновым планом, создайте определение службы для любой подсистемы управления службами вашей системы.

Дополнительная литература

4
18.03.2021, 23:09

Теги

Похожие вопросы