레이싱 프로세스 그룹 ID, 이 그룹을 죽이는 방법은 무엇입니까?

레이싱 프로세스 그룹 ID, 이 그룹을 죽이는 방법은 무엇입니까?

나는 프로세스 그룹을 배우고 있는데, 이는 나에게 새로운 것입니다. (저는 무엇보다도 다음 답변을 따르려고 노력했습니다.SIGINT가 상위 프로세스로 전송될 때 하위 프로세스로 전파되지 않는 이유는 무엇입니까?). 시도했지만 프로세스 그룹의 ID가 사라지는 것 같아서 삭제할 수 없습니다.

$ sleep 1000 &
[1] 6468
$ ps ax -O tpgid | grep sleep
 6468  6511 S pts/4    00:00:00 sleep 1000
 6512  6511 S pts/4    00:00:00 grep --color=auto sleep
$ kill -9 -6511
bash: kill: (-6511) - No such process
$ ps ax -O tpgid | grep sleep
 6468  6515 S pts/4    00:00:00 sleep 1000
 6516  6515 S pts/4    00:00:00 grep --color=auto sleep
$ ps ax -O tpgid | grep sleep
 6468  6517 S pts/4    00:00:00 sleep 1000
 6518  6517 S pts/4    00:00:00 grep --color=auto sleep

왜 이런 일이 발생하며, 어떻게 잡아서 죽일 수 있습니까? 나는 무엇을 얻었고, 무엇을 잘못했는가?

GNU bash, 버전 4.3.42(1)-릴리스(x86_64-pc-linux-gnu)

답변1

이는 프로세스 그룹 ID(PGID)를 인쇄하는 대신 "Control tty Process Group ID" tpgid를 인쇄하기 때문입니다. 설명된 대로 man ps:

   tpgid       TPGID     ID of the foreground process group on the tty
                         (terminal) that the process is connected to, or
                         -1 if the process is not connected to a tty.

따라서 표시되는 것은 포그라운드 프로세스의 PID입니다. 귀하의 경우에는 프로그램입니다 ps.

$ sleep 1000 &
[1] 6745
$ ps ax -O tpgid | grep -E 'sleep|ps a'
 6745  7136 S pts/1    00:00:00 sleep 1000
 7136  7136 R pts/1    00:00:00 ps ax -O tpgid
 7137  7136 S pts/1    00:00:00 grep --color -E sleep|ps a

위에 표시된 것처럼 인쇄된 tpgid 값은 프로세스의 PID입니다 ps. 당신이 찾고 있는 것은 pgid다음이 아닙니다 tpgid:

   pgid        PGID      process group ID or, equivalently, the process ID
                         of the process group leader.  (alias pgrp).


$ ps ax -O pgid | grep -E 'sleep|ps a'
 8414  8414 S pts/1    00:00:00 sleep 1000
 8656  8656 R pts/1    00:00:00 ps ax -O pgid
 8657  8656 S pts/1    00:00:00 grep --color -E sleep|ps a

물론 실제로 어떤 프로세스 그룹도 실행하고 있지 않기 때문에(예를 들어 한 스크립트가 다른 스크립트를 호출할 때 발생) PGID는 sleep해당 PID와 동일합니다. 그러나 원하는 경우 실제로 다음과 같이 죽일 수 있습니다.

$ kill -9 -8414
$ ps ax -O pgid | grep -E 'sleep|ps a'
10065 10065 R pts/1    00:00:00 ps ax -O pgid
10066 10065 S pts/1    00:00:00 grep --color -E sleep|ps a
[1]+  Killed                  sleep 1000

보다 유익한 예는 다음과 같은 스크립트를 실행하는 것입니다.

#!/bin/bash

sleep 1000 &
sleep 1000 &
sleep 1000 &

sleep 1000

이것을 다른 이름으로 저장 foo.sh하고 실행하면 다양한 sleep명령이 모두 동일한 PGID를 갖게 됩니다.

$ foo.sh &
[1] 13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
13555 13555 S pts/1    00:00:00 /bin/bash /home/terdon/scripts/foo.sh
13556 13555 S pts/1    00:00:00 sleep 1000
13557 13555 S pts/1    00:00:00 sleep 1000
13558 13555 S pts/1    00:00:00 sleep 1000
13559 13555 S pts/1    00:00:00 sleep 1000

따라서 각 하위 프로세스는 상위 프로세스의 프로세스 그룹에 속합니다 foo.sh. 지금 프로세스 그룹을 종료하면 모든 프로세스가 종료됩니다.

$ kill -9 -13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
[1]+  Killed                  foo.sh

관련 정보