Jaka jest różnica między Ctrl-Z a kill -STOP?

14

Kiedy uruchamiam polecenie ( makew dużym projekcie) z powłoki, mogę wpisać Ctrl-Z, aby zatrzymać proces i powrócić do powłoki. Następnie mogę uruchomić, fgaby kontynuować proces.

Próbuję napisać skrypt powłoki, aby to zautomatyzować (w szczególności, aby sprawdzać temperaturę mojego procesora co kilka sekund i zatrzymać proces, jeśli robi się zbyt gorąco, ponieważ mój komputer jest podatny na przegrzanie). Moja pierwsza próba działała w ten sposób (uproszczona):

make &
subpid="$!"

sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"

sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"

wait "$subpid"

Niestety to nie zadziałało; wysłanie SIGSTOP do procesu nie wstrzymało go (co widać po dalszym wysyłaniu danych wyjściowych do terminala). Uruchomiłem make &z linii poleceń, wysłałem SIGSTOP i sprawdziłem status procesu za pomocą ps; został wymieniony jako zatrzymany (i zaczął się ponownie, gdy wysłałem SIGCONT), ale nadal wyrzucał moc wyjściową i zwiększał moją temperaturę rdzenia! Zatrzymanie go za pomocą Ctrl-Z nigdy nie miało tego problemu, ale nie wiem, jak to zrobić w skrypcie.

Czym różni się Ctrl-Z kill -STOPi jak mogę uzyskać zachowanie tego pierwszego w skrypcie powłoki?

Taymon
źródło
I tak, makejest uruchamiany rekurencyjnie. W rzeczywistości myślę, że ma kilka poziomów głębokości.
Taymon

Odpowiedzi:

12

Czym różni się Ctrl-Z kill -STOPi jak mogę uzyskać zachowanie tego pierwszego w skrypcie powłoki?

CTRL-Zzwykle wysyła SIGTSTP (który może być zablokowany) i - poza innymi rzeczami - powłoki często resetują tty do wcześniej zapisanego stanu przy takich okazjach. Co ważniejsze jednak, sterująca grupa procesów terminalowych jest ustawiona na PID powłoki (a następnie ponownie na PID zadania wznowionego fg).

Powrót do pierwotnego problemu: zastosowanie skalowania częstotliwości zależnego od temperatury, takiego jak np. Cpufreqd, może być lepszym młotkiem do paznokci.

Peter
źródło
4

Nie chcesz zatrzymać tego makeprocesu; chcesz zatrzymać makeproces i wszystkie jego procesy potomne. Założę się, że make był uruchamiany rekurencyjnie.

Możesz spróbować set -m, a następnie użyć %1zamiast "$subpid".

set -mUmożliwia „kontrolę pracy”, który jest domyślnie wyłączony skryptów wewnątrz. Myślę, że to powinno działać w twoim przypadku użycia, chociaż ludzie wydają się sądzić, że to zły pomysł w ogóle .

sourcejedi
źródło
4

Możesz wysłać sygnał do wszystkich procesów w grupie procesów, jeśli podasz ujemną wartość PID - PGID lidera sesji.

kill -STOP -"$subpid"

Uwaga: Aby uruchomić program w nowej sesji, użyj setsid make. Ale w twoim przypadku myślę, że nie jest to potrzebne. Jeśli jednak make jest uruchamiane rekurencyjnie, każda instancja make może być własnym liderem (nie jestem tego pewien).

Inną opcją może być użycie killall:

killall -STOP make

Różnica między Ctrl + Z a kill -STOP:

  • Ctrl-Z faktycznie wysyła TSTP, który można zablokować.
  • STOP nie może być zablokowany.
Jurij
źródło
Podejście pgid nie działa, a produkowane następujący wiersz wyjścia: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. Procesy w tle nadal działały. Nie sądzę, aby to killallpodejście działało, ponieważ niektóre podprocesy wydają się shraczej być make.
Taymon
Wygląda na to, że proces, na który wysyłasz sygnał, już się zakończył. Podprocesy o nazwie sh są tworzone przez make. W twoim przypadku i wielu podprocesach najlepiej byłoby uzyskać PID wszystkich dzieci i zatrzymać je wszystkie.
Jurij
Skończyło się na tym, że zrobiłem to ręcznie z powłoki, ale nie w skrypcie powłoki. Myślę, że dzieje się tak, ponieważ kiedy zrobiłem to ręcznie, root PID (z którego inni odziedziczyli swój PGID) był pierwszymmake polecenia, ale kiedy zrobiłem to ze skryptu, główny identyfikator PID pochodził z samego skryptu powłoki .
Taymon
1

Ctrl+ Csłuży do zabicia procesu sygnałem SIGINT, innymi słowy jest to grzeczne zabicie .

Ctrl+ Z służy do zawieszenia procesu poprzez wysłanie mu sygnału SIGSTP , który jest jak sygnał uśpienia, który można cofnąć i proces można wznowić ponownie.

Jednak gdy proces zostanie zawieszony, możemy go wznowić do fg (wznowienie na pierwszym planie) i bg (wznowienie w tle) , ale nie mogę wznowić zabitego procesu, to jest różnica między używaniem Ctrl+ Ci Ctrl+ Z.

Jak wyświetlić zawieszony proces?

Jeśli masz wiele zawieszonych poleceń, aby je wyświetlić, użyj jobspolecenia, a wynikiem będzie:

[1]-  Stopped                 cat
[2]+  Stopped                 vi

Jak zabić zawieszony proces w tle?

Za pomocą killpolecenia:

kill %ngdzie n to numer zadania (ten w nawiasach kwadratowych z danych wyjściowych zadań), więc chcę zabić kota:kill %1 .

antzshrek
źródło