본문 바로가기
목차
Linux

Linux 커널 관점에서 이해하는 Session, Process Group, Process, Thread와 Job Control의 실제 동작

by ds31x 2026. 1. 9.
728x90
반응형

1. Linux 커널 관점에서의 Inclusion Heirarchy of Execution Units

session
 └─ process group
       └─ process
              └─ thread (= task (=task_struct), kernel scheduling unit)

Linux 커널에서

  • 스케줄링의 최소 단위(scheduling entity)는 thread(task_structy) 이며
  • process는 thread들의 컨테이너 역할을 하며, thread들의 집합이라고 볼 수 있음.

The scheduler schedules
tasks,
not processes.

 

참고로, thread는 light weight process (LWP) 라고도 불림.

 

주의할 점은 Multi-tasking 에서 나오는 task(OS관점에서의)와 커널 관점에서의 task는 다른 개념임:

OS 관점에서 말하는 task는 커널의 task(thread)보다는, shell이 관리하는 job 개념(=process group)에 더 가깝다.

 

OS관점에서의 task는 다음을 참고:

 

각 execution unit에 대해 살펴보면 다음과 같음:

  • 스케줄링 단위: thread(task)
  • 자원 소유 단위: process
  • 터미널 제어 단위: process group
  • 로그인 단위: session

Session은
하나의 터미널을 중심으로 생성된 프로세스들을
동일한 실행 맥락(context)으로 묶어 관리하기 위한 커널의 실행 컨텍스트

 

Context란, 커널이 실행 흐름을 구분하고 관리하기 위해 사용하는 논리적 실행 환경을 의미.

1-1 thread (커널 관점에서 task)

Linux 커널에서 스케줄링의 단위임.

  • Linux 커널 내부 구조체로 구현됨: task_struct
  • 커널은 process를 직접 스케줄링하지 않음
  • 각 thread가 개별적으로 스케줄링됨

특징:

  • thread마다 TID 존재
  • 같은 process의 thread들은
    • 주소 공간 공유
    • 파일 디스크립터 공유
  • ps -L, /proc/<pid>/task/ 로 확인 가능

Linux에서 “thread = task”임.
OS관점인 Multi-task system에서의 task는
좀 더 넓은 개념(=job, process group)으로
Linux 커널 관점의 task와 구분됨.


1-2 process

Threads 의 그룹

  • 하나 이상의 thread(task)를 포함하는 논리적 실행 단위
  • PID = main thread의 TID
  • 주소 공간과 자원(Resource)의 소유자

관계:

  • single-thread process : task 1개
  • multi-thread process : task 여러 개

리눅스 커널이 아닌 일반적인 관점에서의 Process와 Thread는 다음을참고:


1-3 process group

job control을 위한 묶음 (Session에서 job에 해당하며, OS관점에서의 task에 해당)

  • 여러 process를 하나의 그룹으로 관리
  • 같은 그룹은 하나의 PGID 공유
  • 터미널 신호는 process group 단위로 전달
    • 터미널 신호는 터미널에서 발생하는 Signal임 (커널의 TTY Layer 에서 이루어짐)
    • SIGINT : User Interrupt (Ctrl + c)
    • SIGTSTP : Terminal SToP (Ctrl + z)
  • kill 명령어로 Signal을 보낼 때는 Process 단위로 전달됨.
    • 물론 procss group으로도 가능.
    • PGID는 음수로 표기함: -1234 는 PGID가 1234임 (PID랑 구분하기 위해.
    • kill -TERM -1234 or kill -TERM -- -1234: PGID 1234 인 프로세스들에 SIGTERM 을 보냄(-TERM).
      • -- 는 옵션이 끝났음을 의미함.

참고: signal과 kill에 대한 보다 자세한 내용은 다음을 참고:


1-4 session

Session은 터미널 로그인과 그로부터 파생된 모든 실행 흐름을 묶는 커널 수준의 최상위 실행 컨텍스트.

  • 터미널 로그인 단위의 최상위 컨테이너: SID (Session ID)를 가짐.
  • 하나의 session은 여러 process group을 포함 (최소 한 개이상을 가짐) 
  • 터미널(TTY, TeleTYpe)은 session 단위로 귀속
  • session에는 하나의 session leader가 존재: session leader 프로세스의 PID가 해당 session의 SID임
  • foreground / background process group 관리 는 한 session에서 이루어짐:
    • fg와 bg의 차이는 터미널 제어권이며 1개의 session이 1개의 터미널(tty)임.
    • 즉, 동일 session이어야만 동일 tty를 가지며,
    • 이에 대한 제어권 관리가 이루어지려면, process group들이 모두 동일 session에 속해야 함.

2. 현재 shell의 구조 확인 (session / process / thread)

2-1 shell의 session 정보

ps -o pid,ppid,pgid,sid,tty,cmd -p $$
  • -o : 출력할 columns 를 지정.
  • -p : 출력할 process 를 지정 (PID로)
  • $$ : 현재 Shell의 PID 를 값으로 가지는 shell변수.

ps에 대한 보다 자세한 건 다음을 참고:

 

예:

PID   PPID  PGID   SID   TTY     CMD
1234  1000  1234  1234  pts/0   bash

 

해석:

  • shell이 session leader: PID과 SID가 같음.
  • 자신만의 process group 소유
  • 하나의 main thread(task)만 존재

2-2 shell의 thread 확인

ps -L -p $$
  • -L : 프로세스가 보유한 모든 thread(LWP)를 각각 한줄로 출력하라는 옵션.
PID   LWP   TTY   STAT CMD
1234  1234  pts/0 Ss   bash
  • LWP(Light Weight Process) = thread(task)
  • 즉, bash는 단일 thread process

3. thread가 여러 개인 process 를 확인해보기: top

기본 포함된 프로그램 top를 사용:

top &
  • & 를 붙이면 background로 실행됨.

PID 확인 후:

ps -L -p <top의_PID>

이의 결과는 보통 다음과 같은 형태임.

 

PID   LWP   STAT CMD
2345  2345  S    top
2345  2346  S    top
2345  2347  S    top
  • 하나의 process
  • 여러 thread(task)
  • 커널은 이 thread들을 각각 스케줄링

job control 대상은
이 process가 속한 process group임
thread가 아닌 점에 주의!


참고: Job은 Foreground와 background로 나뉨:

  • Foreground job은 터미널의 입력과 제어 신호를 직접 받아 실행 중인 process group을 의미.
    • Foreground job은 터미널을 직접 점유하며, 표준 입출력이 모두 터미널에 연결
    • stdin (표준 입력)
      • 터미널 입력과 직접 연결
      • 키보드 입력을 바로 읽을 수 있음
    • stdout (표준 출력)
      • 터미널 화면으로 출력
      • printf, echo 결과가 즉시 보임
    • stderr (표준 오류)
      • 터미널 화면으로 출력
      • 오류 메시지도 즉시 표시됨
  • Background job은 터미널의 제어권을 갖지 않은 채, shell의 제어 하에 비동기로 실행되는 process group을 의미.
    • Background job은 터미널 제어권을 가지지 않으며, 표준 입력은 제한되고 출력만 터미널로 전달
    • stdin (표준 입력)
      • 터미널 입력과 논리적으로 분리
      • 읽으려고 하면 보통 SIGTTIN 발생 => job 중지
      • 사실상 입력 불가
    • stdout (표준 출력)
      • 기본적으로 터미널로 출력됨
      • 단, 출력은 터미널을 점유하지 않음
    • stderr (표준 오류)
      • 기본적으로 터미널로 출력됨
      • foreground job과 동일

터미널을 점유한다 = 해당 process group이 터미널의 foreground process group으로 설정.
다음이 가능한 process group임:
터미널 제어신호 수신.
터미널 설정 변경이 가능.

 

 

stdin, stdout, stderr 와 같은 표준 스트림에 대해서 좀 더 자세한 건 다음을 참고:

 


4. job control 실습 (process group 중심) : sleep 명령어

4-1 background job 생성

sleep은 지정한 시간(sec) 동안 현재 프로세스를 일시 정지(suspend)시키는 표준 유닉스 명령어

sleep 100 &
  • sleep 100을 새로운 process group으로 생성
  • 현재 shell을 점유하지 않는 background job으로 실행

출력은 다음과 같음: & 를 통해 백그라운드로 실해시킬 경우 job ID와 process ID를 보여줌.

[1] 3456
  • [1] : shell이 부여한 job 번호(job ID)
    • 현재 Shell(session) 안에서 job control을 위해 사용
    • fg %1, bg %1, kill %1 처럼 참조 가능
  • 3456 : 백그라운드로 생성된 process group의 PID

4-2 job 목록 확인

jobs는 현재 shell이 생성하고 추적 중인 background / stopped job 목록을 출력하는 shell의 built-in command(내장명령어)

  • job = process group
jobs

 

결과는 다음과 같은 형태로 나옴:

[1] Running sleep 100 &

 

jobs 명령어에 대한 자세한 건 다음을 참고:


4-3 process / group / session 구조 확인

ps -o pid,pgid,sid,tty,cmd | grep sleep
  • 각 프로세스의 PID / PGID / SID / TTY / 명령어를 함께 출력
  • 그중 sleep 프로세스만 확인

다음의 형태의 출력이 나옴:

3456  3456  1234  pts/0  sleep 100

 

같은 터미널에서 shell을 보면:

1234  1234  1234  pts/0  bash
  • sleep
    • shell과 같은 session (SID로 3번째 열) : 1234
    • 다른 process group (PGID로 2번째 열) : 3456
  • 즉, sleep은 shell과는 다른 독립적인 job(process group) 으로 실행

Interactive shell은 각 job을 실행할 때, foreground / background 여부와 무관하게 새로운 process group을 생성

참고로 shell을 ps로 살펴보면 여러 개가 보일 수 있는데 이는 subshell 이 만들어지기 때문임:
zsh 등은 subshell을 다음의 경우 subshell을 만드는데 각 subshell은 독립된 process group을 가짐.
1. pipe 사용시 : cmd1 | cmd2
2. commnad substition 사용시 : echo $(some_command)
3. 그룹 실행 : ( cd /tmp; ls )

5. Ctrl+Z: process group 단위 중지

5-1 foreground 실행

sleep 100
  • sleep외부 명령어이므로 새로운 process로 실행됨
  • interactive shell은 이 명령을 위해 새로운 process group을 생성
  • 해당 process group을 foreground process group으로 설정
  • 그 결과, 터미널 입력과 Signal(Ctrl+c, Ctrl+z)은 이 process group으로 전달됨

shell은 실행이 끝날 때까지 대기(block) 상태가 됨


5-2 중지

Ctrl + z
  • Ctrl+z는 터미널에서 발생한 입력 이벤트 임.
  • 터미널(TTY) 드라이버가
    • 현재 foreground process group 전체를 대상으로
    • SIGTSTP 신호(Terminal SToP)를 전송
  • 커널은 해당 process group에 속한
    • 모든 process들에
    • 각 process의 모든 thread(task) 를 일괄 중지

다음의 결과가 출력된 경우:

[1] Stopped sleep 100
  • Shell은 중지된 process group을
    • 하나의 job으로 등록하고
    • [1]이라는 job 번호를 부여
  • 이후 이 job은 jobs, fg, bg로 제어 가능

6. bg / fg로 상태 전환

6-1 background로 재개(Resume, SIGCONT)

bg # or bg %JOD_ID
  • Ctrl+z로 중지(stopped) 상태에 있는 job(process group) 을 선택하여 백그라운드 실행 상태로 전환
  • 해당 process group에 SIGCONT 신호를 전송
  • 해당 job은 background 상태로 계속 실행
    • 터미널의 foreground process group은 여전히 shell
  • background job에서 표준 입력(stdin)은 차단됨
  • 단, 표준 출력(stdout)과 오류(stderr)는 터미널로 출력 가능

6-2 foreground 복귀

fg # or fg %JOD_ID
  • 중지되었거나 background에 있던 job(process group) 을 선택
  • 해당 process group에 SIGCONT 신호를 전송
  • 동시에, 해당 process group을 foreground process group으로 설정
    • 터미널의 제어권이 shell => 해당 job으로 이동
  • job이 종료되거나 다시 중지될 때까지
    • shell은 대기(block) 상태가 됨
  • stdin / stdout / stderr가 모두 터미널과 직접 연결됨

7. 파이프라인 + thread + job control

이 예제를 통해 파이프라인이

  • process는 여러 개지만
  • job control 대상은 하나의 process group임을
    같은 TTY에서 실제로 확인할 수 있음

7-1 실행

 

sleep 100 | cat
  • A | B 는 Shell이 두 개의 프로세스를 생성해 연결하는 Pipeline 실행.
    • 왼쪽 프로세스(sleep)의 stdout(쓰기) => 파이프
    • 오른쪽 프로세스(cat)의 stdin(읽기) <= 파이프
  • shell 은 이 파이프라인 전체를 하나의 job으로 취급해야 하므로,
    • 두 프로세스를 같은 process group(PGID) 에 넣습니다.
  • 이는 foreground 실행이므로, shell은 이 process group을 foreground process group으로 설정
    • 파이프라인이 끝날 때까지 shell은 대기.

즉, 파이프라인 은 여러 process 로 구성되지만 job control 대상은 하나의 PG(process group) 임.

 

pipe에 대해 보다 자세한 건 다음을 참고:

Ctrl+z 를 수행하고 다음의 명령어로 이를 확인할 수 있음:

ps -o pid,pgid,sid,tty,cmd | grep -E 'sleep|cat'
  • PID: sleepcat은 서로 다른 PID 를 가짐 = 프로세스 2개
  • PGID: 둘이 같은 PGID => process group 1개 (하나의 job )
  • SID: 둘이 같은 SID => 같은 session(같은 터미널 로그인 흐름)
  • TTY: 같은 pts/X => 같은 터미널에 속함.

7-2 Ctrl + z 가 파이프 라인 전체를 중지시킴

Ctrl+z를 누르면:

  1. 터미널(TTY)은 “현재 foreground로 지정된 process group”을 알고 있는 상태임.
  2. Ctrl+z 입력은 터미널 드라이버에 의해 foreground process group 전체에 SIGTSTP로 전달.
  3. 그 foreground process group에는 sleepcat이 함께 들어있기 때문에 두 프로세스가 동시에 중지됨.
  4. 각 프로세스는 중지되면서, 그 프로세스 내부의 모든 thread(task) 도 실행이 멈춘 상태가 됨.

Ctrl+z는 “프로세스 하나”가 아니라 “foreground process group”을 타겟으로 하므로 파이프라인 전체가 멈춤.


7-3 Job Control

중지된 뒤 jobs를 통해 job id 등을 확인:

jobs

출력은 다음과 같은 형태임:

[1]  Stopped                 sleep 100 | cat

즉, shell 은 파이프라인 전체를 하나의 job([1]) 으로 관리

 

이때 fg, bg는 프로세스가 아니라 process group을 대상으로 동작.

멈춘 job을 재개하려면:

bg %1

이를 foreground로 가져오려면:

fg %1

같이보면 좋은 자료

2024.05.14 - [CE] - [CE] Process State (or Process Life Cycle)

 

[CE] Process State (or Process Life Cycle)

Process States (or Process Life Cycle)이는 프로세스가 가질 수 있는 상태를 가르키며, 프로세스의 life cycle을 보여준다. 프로세스는 프로그램이 실행되기 위해 메인메모리에 적재된 프로그램의 instance라

ds31x.tistory.com

 

728x90