본문 바로가기
책 정리/리눅스 커널 내부구조

태스크 관리

by ocean20 2023. 4. 19.

1. 프로세스와 스레드 그리고 태스크
program : 디스크에 저장되어 있는 실행 가능한 파일
process : running or runnable program
task : 자원 소유권의 단위

2. 사용자 입장에서의 프로세스 구조
32bit CPU의 경우 운영체제는 각 프로세스에게 총 4GB 크기의 가상공간을 할당
0~3GB 사용자
3~4GB 커널
사용자공간에서는 text, data, heap stack 총 4가지 region으로 구분가능
text : cpu에서 직접 수행되는 명령어(instructions)
data : 전역변수
stack : 지역변수와 인자 그리고 함수의 리턴주소
heap : 동적할당 영역
각 영역을 segment 또는 vm_area_struct 라고도 부름.

3. 프로세스와 쓰레드의 생성과 수행
프로세스 생성방법 : fork() vfork()
프로세스가 생성되면 주소공간을 포함하여 이 프로세스를 위한 모든 자원들이 새로 할당된다.(=복사 비용이 크다.) 즉 각각의 프로세스의 연산결과는 서로 영향을 주지 않는다.
fork()시 각각의 프로세스의 getpid()의 리턴값은 다르다.
쓰래드 생성방법 : clone(), pthread()
새로 생성된 쓰레드는 기존 쓰레드와 getpid()의 리턴값이 동일하기에 새로운 프로세스가 생성되지 않음.
즉, 1개에 프로세스에 2개의 쓰레드가 동작 = 다중 스레드 시스템
즉 기존에 수행되던 쓰레드는 자신이 생성한 스레드에서 값 수정시, 기존스레드에서 반영됨을 볼 수 있다.

4. 리눅스의 태스크 모델
이제 사용자가 아닌 커널단에서 process, thread를 어떻게 구현하는지 확인해보자.
리눅스는 프로세스마다 task_struct라는 자료구조를 생성한다. 이와 동일하게, 스레드 생성시에도 각 스레드마다 task_struct라는 동일한 자료구조를 생성하여 관리한다.
이러한 1대1 모델(ex. 스레드 1개에 커널 수준 자료구조(task_struct) 1개 대응)의 개념은 커널함수를 통해 더 자세하게 살펴볼수 있다.
앞서 살펴본 app단에서 호출가능한 함수인 fork(), clone()은 모두, 커널에 sys_clone()이라는 시스템호출을 사용한다. 왜 스레드와 프로세스는 같은 함수를 사용할까? 그 이유는 리눅스입장에서 태스크를 생성하기 때문이다.
그렇다면 task_struct만 가지고 프로세스와 스레드를 구분하는 방법은?
→ 우선 task_struct는 pid를 key로 유일하게 구분된다. 그러나 한프로세스내의 스레드는 동일한 pid를 공유해야한다. 따라서, tgid(Thread Group ID)라는 개념을 도입함.
ex) 프로세스 생성시 우선 태스크가 만들어지고, pid가 1번, 또한 tgid도 pid와 동일한 1번으로 정해짐. 여기서 프로세스 fork()시 pid 2 tgid 2 , 만약 pid1번에서 스레드 생성시, pid 3 tgid 1이 생김.
! 우리가 여태껏 알던 getpid()를 통해 얻은 pid는 실은 tgid 였던 것이다!!

.. 진행중 ..

댓글