나는 다음 두 가지 소스로부터 결정적으로 결론을 내렸습니다: Shell의 프로세스 그룹 ID = 포그라운드 작업 프로세스 그룹 ID. 포그라운드에서 실행되도록 백그라운드 작업을 선택하면 쉘의 프로세스 그룹 ID가 포그라운드 작업의 프로세스 그룹 ID로 변경됩니까, 아니면 그 반대로 변경됩니까?
1.
작업 제어 사용자 인터페이스의 구현을 용이하게 하기 위해 운영 체제는 현재 터미널 프로세스 그룹 ID의 개념을 유지합니다. 이 프로세스 그룹의 멤버(현재 터미널의 프로세스 그룹 ID와 동일한 프로세스 그룹 ID를 가진 프로세스)는 SIGINT와 같은 키보드 생성 신호를 수신합니다. 이러한 프로세스를 포그라운드에 있다고 합니다. 백그라운드 프로세스는 프로세스 그룹 ID가 터미널 프로세스 그룹 ID와 다른 프로세스입니다. 이러한 프로세스는 키보드에서 생성된 신호의 영향을 받지 않습니다.(원천)
2.
다음에 추가:
$sleep 3000 &
$sleep 2000 &
$ps xao pid,ppid,pgid,sid,tty,comm | grep tty
PID PPID PGID SID TTY COMMAND
1153 1135 1153 1153 tty1 bash
1173 1153 1173 1153 tty1 sleep
1189 1153 1189 1153 tty1 sleep
1219 1153 1219 1153 tty1 ps
1220 1153 1219 1153 tty1 grep
답변1
나는 다음 두 가지 소스로부터 결정적으로 결론을 내렸습니다: Shell의 프로세스 그룹 ID = 포그라운드 작업 프로세스 그룹 ID.
인용한 소스 중 어느 것도 셸의 PGID가 포그라운드 작업 PGID와 동일하다고 주장하지 않기 때문에 이렇게 하면 안 됩니다.
쉘의 PGID는 변경되지 않습니다. 터미널에서 대화형 쉘을 실행할 때 일반적인 상황에서 쉘은 자체 프로세스 그룹에 있고 쉘의 PGID는 쉘의 PID와 같습니다.
모든 프로세스에는 PGID가 있습니다. 터미널에는연관된 포그라운드 프로세스 그룹 ID. 정의에 따르면 포그라운드 프로세스 그룹은 이 PGID를 가진 프로세스 그룹입니다.
터미널이 터미널 에뮬레이터에서 제공되는 경우 이는 터미널 에뮬레이터 프로세스의 PID와 관련이 없습니다. 커널이 전적으로 제공하는 하드웨어 터미널을 고려한다면 이는 명백합니다. 이 경우에는 터미널 에뮬레이터 프로세스가 없습니다.
터미널과 연결된 PGID를 전달할 수 있습니다.tcsetpgrp
쉘이 포그라운드에서 외부 프로그램을 시작하거나 를 사용하여 작업을 포그라운드로 이동할 때 호출되는 함수입니다 fg
.
답변2
아이디어는 1979-1980년경 Bill Joy의 csh에서 나왔습니다. Bill Joy는 이 기능을 활성화하기 위해 관련 커널 지원을 추가했습니다.
당시 원본 csh는 vfork() 지원으로 작성되었기 때문에 csh의 코드를 이해하기 어려웠습니다. vfork()는 자식의 작업에서 부모의 효과를 복원해야 하고 자식의 작업은 다음과 같았기 때문입니다. vfork()에서 부모와 자식 간의 공유 메모리 결과입니다.
작동하는 구현을 보려면 Bourne Shell 소스 코드를 읽어 보는 것이 좋습니다.
쉘은 시작 시 자신이 프로세스 그룹 리더인지 확인하고 필요한 경우 자신을 프로세스 그룹 리더로 만듭니다.
물론 쉘은 시작 시 프로세스 그룹 리더가 아니고 자체적으로 유지되는 것을 선호하지 않는 한 수명 동안 이 ID를 유지합니다. Bash는 이것을 완전히 지원하지 않습니다.
시작된 작업을 더 쉽게 관리할 수 있도록 각 작업은 새로운 별도의 자체 프로세스 그룹 ID에서 실행됩니다.