Chapter 3 - 태스크 관리(2)

2022. 9. 19. 01:07개발 관련 책 읽기/리눅스 커널 내부구조

 

 

위의 그림은 리눅스에서 프로세스와 스레드를 관리하기 위한 커널 자료 구조를 보여준다

리눅스에서는 프로세스가 생성되는 스레드가 생성되든 task_struct라는 자료구조를 생성한다

결국 리눅스 커널은 프로세스 or 스레드 중에서 어떤 것이 요청될지라도, 모두 task_struct 자료 구조로 동일하게 관리한다

 

단지 task_struct 자료 구조 중에서 수행 이미지를 공유하는가, 같은 스레드 그룹에 속해 있는가 등의 여부에 따라 프로세스 또는 스레드로 사용자에게 해석되는 차이가 있을 뿐이다.

 

결국 리눅스는 1대 1 모델 기반으로 한다 이러한 구현은 기존의 운영체제와는 다른 리눅스 특유의 태스크 개념을 유도한다

리눅스에서는 프로세스이던 스레드이던 커널 내부에서는 태스크라는 객체로 관리된다.

 

태스크가 관리하는 자원을 어떻게 공유하고 접근 제어하느냐에 따라서 프로세스 / 스레드로 해석된다

 

위의 그림은 태스크 생성과 관련된 함수의 흐름이다.

사용자의 프로세스 혹은 스레드 생성 요청은 라이브러리의 함수를 거쳐 시스템 콜을 통해 리눅스 커널에 전달된다. fork(),clone(),pthread_create()는 커널에 구현되어 있는 clone() -> sys_clone() 시스템 콜을 사용하며, vfork()는 sys_vfork()를 사용한다.

 

sys_clone(),sys_vfork()는 모두 커널 내부 함수 do_fork()를 호출한다

fork는 프로세스를 생성하는 함수이고, clone은 스레드를 생성하는 함수인데 커널 내부에서 마지막으로 호출되는 함수 do_fork로 동일하다.

 

어떻게 이런 일이 가능할까? 커널에겐 모두 태스크로 인식되기 때문이다

 

그러면 do_fork 함수는 어떤 일을 수행할까?

task_struct 구조체를 생성한 후 해당 정보를 저장하는 역할을 수행하게 된다

 

task_struct 구조체 내에 태스크를 식별하기 위한 pid 필드가 있다.

POSIX 표준에 의하면 '한 프로세스 내의 스레드는 동일한 PID를 공유해야 한다'라고 명시되어 있다.

리눅스에서는 이를 위해 tgid(Thread Group ID)를 도입했다.

 

fork, vfork 함수를 실행한 결과 부모 프로세스와 자식 프로세스의 pid는 서로 달랐고

각각의 프로세스의 pid 와 tgid는 서로 같았다.

pthread_create 함수를 실행한 결과 부모 스레드와 자식 스레드의 tgid 값이 서로 같았다.

 

gettid 시스템 꼴은 pid 값을 출력해주는 함수이다

getpid()는 tgid 필드 값을 리턴해주는 함수이다.

 

 

 

반응형