ARM Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

0239
1625
172602


[리눅스커널] Process - 프로세스, 경량 프로세스, 스레드 소개 4. 프로세스(Process) 관리

프로세스라는 개념은 모든 멀티프로그래밍 운영체제의 기본입니다.
프로세스는 실행중인 프로그램의 인스턴스로 정의할 수 있는데, 16명의 유저가 vi를 동시에 실행하면 각각 16개의 프로세스가 존재합니다. (물론 vi 코드는 동일한 것을 공유할 수 있습니다). 
리눅스 코드에서는 프로세스를 태스크(task)나 쓰레드(thread)라고 부릅니다.

프로세스, 경량 프로세스 그리고 쓰레드
프로세스라는 용어는 여러가지 다른 추상화 개념으로 씁니다. 프로세스는 프로그램이 어디까지 실행되었는지를 완벽하게 알고 있는 자료 구조체라 볼 수 있습니다. 

프로세스는 마치 인간과 같습니다. 프로세스는 생성되고 중요하게 관리될 수 있으며 사소하기도 한 삶을 살고, 자식 프로세스를 생성하기도 하고 마지막에는 죽습니다. 
아주 작은 차이가 있다면 프로세스 사이에서는 성별이랑 관계없는 부모 하나만 있다는 겁니다. 

커널 입장에서 프로세스는 시스템 자원을 할당받는 개체입니다. 

프로세스가 생성될 때 부모 프로세스와 거의 동일합니다. 부모의 주소 공간을 물려받고, 부모와 동일한 코드를 실행합니다(프로세스를 생성하는 코드 이후의 명령어를 시작으로 실행을 한다). 부모와 자식은 프로그램 코드가 들어있는 text 페이지는 공유하고 데이터 영역(스택과 힙)은 별도로 갖게 되어, 자식 프로세스가 메모리의 특정 위치에 수정한 내용을 부모가 모를 수도 있습니다.

초기의 유닉스 커널에서는 이런 간단한 모델을 채용했지만, 근래의 유닉스 시스템은 그렇지 않스빈다. 근래의 유닉스 시스템은 멀티쓰레드 애플리케이션이라는 것을 지원하는데, 이는 하나의 유저 프로그램이 애플리케이션 자료 구조를 상당부분 공유하면서 독립적으로 코드를 실행하는 쓰레드를 갖습니다. 이런 시스템에서는 프로세스가 여러개의 유저 쓰레드(또는 그냥 쓰레드)로 구성되어 있고, 각 쓰레드는 프로세스의 실행 흐름을 나타냅니다. 요즘에는 대부분의 멀티쓰레드 애플리케이션이 pthread(POSIX thread) 라이브러리라는 표준 라이브러리 함수를 이용하여 작성합니다. 

예전 버전 리눅스 커널은 멀티쓰레드 애플리케이션을 지원하지 않았습니다. 커널 관점에서 멀티쓰레드 애플리케이션이라는 것은 그냥 프로세스일 뿐이었습니다. 멀티 쓰레드 애플리케이션의 여러 실행 흐름들은 POSIX 계열의 pthread 라이브러리를 통해 전히 유저 모드에서 생성되고 처리되고 스케줄됐습니다. 

그러나 멀티쓰레드를 그런 식으로 구현하는 것은 신통치 않았습니다. 예를 들어 체스 프로그램이 두 개의 쓰레드를 사용한다고 하자. 한 쓰레드는 사용자가 체스를 옮길 때까지 기다리면서 그래픽 체스 보드를 건트롤하고 컴퓨터 플레이어가 체스 옮기는 것을 보여주고, 다른 쓰레드는 그 다음 번에 체스를 어디로 움직어야 할지 고민합니다. 첫 번째 쓰레드가 사용자가 체스를 움직이길 기다리는 동안에 두 번째 쓰레드는 계속해서 실행되어야 하므로 사용자가 생각하는 시간을 활용해야 합니다. 하지만 체스 프로그램이 단일 프로세스라면, 첫번째 쓰레드가 사용자의 액션을 기다리라는 시스템 콜을 호출하면 블럭킹되어 두번째 쓰레드까지 블럭킹됩니다. 대신에 프로세스가 계속해서 실행될 수 있게 복잡한 논블럭킹 테크닉을 채용해야 합니다. 

리눅스는 경량 프로세스를 사용하여 멀티쓰레드 애플리케이션을 지원합니다. 기본적으로 두개의 경량 프로세스들은 주소 공간, 파일 등의 리소스를 공유합니다. 두 프로스세스 중 하나가 공유 리소스를 수정하면, 나머지 프로세스도 이를 즉시 알 수 있습니다. 물론 두 프로세스가 공유 리소스를 접근할 때에는 동기화를 이뤄야 합니다. 

멀티쓰레드 애플리케이션을 구현하는 직관적인 방법은 각 쓰레드를 경량 프로세스와 연관지으면 됩니다. 이로 쓰레드들은 동일한 메모리 공간과 파일을 공유하여 애플리케이션 자료 구조에 접근할 수 있습니다. 동시에 각 쓰레드는 커널에 의해 독립적으로 스케줄되기 때문에 한 쓰레드가 일을 하는 동안에 한 쓰레드는 슬립에 들어갈 수 있습니다. POSIX 계열의 리눅스 경량 프로세스를 사용하는 예로는 LinuxThreads, Native POSIX Thread Library (NPTL), IBM’s Next Generation Posix Threading Package (NGPT)가 있습니다. 

POSIX 계열의 멀티쓰레드 애플리케이션은  쓰레드 그룹을 지원하는 커널에 의해 가장 잘 처리합니다. 리눅스에서 쓰레드 그룹은 기본적으로 멀티쓰레드 애플리케이션을 구현하는 경량 프로세스 집합이며 getpid(), kill(), _exit() 같은 시스템 콜에 대해서 하나의 묶음으로 동작합니다.


덧글

댓글 입력 영역