#linux #bash #child-process #ps #suspend
#linux #bash #дочерний процесс #ps #приостановить
Вопрос:
У меня есть этот фрагмент кода в скрипте. Вот сценарий, test.sh
который иллюстрирует это:
#!/bin/bash
$@ amp;
pid=$!
#kill -STOP $pid
echo "PID = $pid"
echo '$@ = '"$@"
ps -p $pid -o uname,pid,command
echo
ps -A -o uname,pid,stat,command | grep 'script.sh' | grep -v grep
#kill -CONT $pid
wait $pid
exit 0
kill
команды закомментированы, это предназначено. Что происходит:
- Я запускаю этот скрипт с другим сценарием в качестве аргумента:
./test.sh ./script.sh
test.sh
запускает./script.sh
, записывает егоPID
и показывает информацию- Информация показывает дочерний PID и процесс, соответствующий
./script.sh
root@test# ./test.sh ./script.sh
PID = 53370
$@ = ./script.sh
USER PID COMMAND
root 53370 /bin/bash ./script.sh <-- Child process
USER PID STAT COMMAND
root 53369 S /bin/bash ./test.sh ./script.sh <-- Current process
root 53370 S /bin/bash ./script.sh <-- Child process
Все нормально.
Теперь, если я раскомментирую kill
команды, скрипт отобразит эту информацию:
root@test# ./test.sh ./script.sh
PID = 53422
$@ = ./script.sh
USER PID COMMAND
root 53422 /bin/bash ./test.sh ./script.sh <-- Child process
USER PID STAT COMMAND
root 53421 S /bin/bash ./test.sh ./script.sh <-- Current process
root 53422 T /bin/bash ./test.sh ./script.sh <-- Child process
Я не уверен, что понимаю, почему, когда я приостанавливаю свой дочерний процесс, я получаю точно такое же COMMAND
значение для моего текущего процесса и моего дочернего процесса на ps
выходе.
Почему это происходит? Я хотел бы понять механизм взаимодействия родительского и дочернего процессов в этой ситуации.
Комментарии:
1. Хорошо, добавление
sleep 0.01
между созданием дочернего процесса иps
изменением выходных данных дало мне тот же результат, что и без приостановки процесса. Так что, я думаю, это не имеет ничегоkill -STOP
общего с тем, как создается процесс? И я просто слишком быстро приостанавливал дочерний процесс, чтобы увидеть его фактическую командную строку? Остается вопрос: почему я вижу командную строку родителя? Как это работает?
Ответ №1:
Потому что вы остановили дочерний процесс, пока он находился между fork()
и execve()
, прежде чем он смог выполнить script.sh
сценарий.
Добавьте a sleep 1
перед kill -STOP
, чтобы увидеть эффект.
A fork()
создает дочерний процесс как копию родительского процесса (что означает, что он будет отображаться в ps
выходных данных с тем же именем процесса, аргументами командной строки и почти всем остальным, кроме pid). Когда дочерний элемент вызывает execve()
системный вызов, он заменяет все это.
После a fork()
нет гарантии, какой из родительских или дочерних процессоров будет запущен первым (и фактически, они могут выполняться одновременно на разных процессорах, или любой из них может быть вытеснен на неопределенный срок) — и любые «философские» выводы, сделанные из порядка, в котором они выполняют разные операции wrtдруг друга совершенно бессмысленно 😉
Комментарии:
1. Ах, я не знал
fork()
, что такое поведение. Я провелsleep
тест, и действительноps
, вывод показываетCOMMAND
значение послеexecve()
системного вызова, и оно выглядит так, как оно должно выглядеть в конце. Спасибо за объяснение