1. 쓰레드란 무엇인가?

* 멀티 프로세스 기반 프로그램

: 서로 다른 프로그램을 실행시키기 위해서 다른 프로세스를 생성하는 것 처럼, 하나의 프로그램이 둘 이상의 일을 동시에 처리하기 위해서 둘이 상의 프로세스를 필요로 한다.

* 멀티 프로세스 운영체제 기반 프로그램의 문제점과 새로운 제안

: 많은 수의 프로세스 생성은 빈번한 컨텍스트 스위칭(Context Switching : 레지스터에 프로세스의 상태 정보를 저장하고 복원하는 일련의 과정)으로 이어져 성능에 영향을 미치기 때문에 부담스러운 작업이다.

: 저장하고 복원하는 컨텍스트 정보의 개수를 줄여준다면, 그 부담을 줄어들 것이다. 컨텍스트 정보란 프로세스 상태정보를 뜻한다.

: A프로세스와 B프로세스가 부모 자식관계라도 일단 생성되고 나면 완전히 별개의 프로세스가 된다.

: 그런데 A프로세스와 B프로세스가 완전히 별개가 아닌 50% 정도만 별개이고 나머지는 공유하는 구조라면 컨텍스트 스위칭의 부담도 반으로 줄지 않을까? 이것이 쓰레드의 탄생한 배경이다.

* 해결책, 쓰레드

: 하나의 프로그램 내에서 둘 이상의 프로그램 흐름을 만들어내기 위해 디자인되었다. 쓰레드간에는 공유하는 상태 정보들이 있기 때문에 이것이 쓰레드의 컨텍스트 스위칭을 빠르게 하는 요인이 된다.

- 쓰레드는 하나의 프로그램 내에서 여러 개의 실행 흐름을 두기 위한 모델이다.

- 쓰레드는 프로세스처럼 완벽히 독립적인 구조가 아니다. 쓰레드들 사이에는 공유하는 요소들이 있다.

- 쓰레드는 공유하는 요소가 잇는 관계로 컨텍스트 스위칭에 걸리는 시간이 프로세스 보다 짧다.

* 메모리 구조 관점에서 본 프로세스와 쓰레드

: 자식 프로세스 생성후 메모리 구조는 서로 아무리 관계가 없게 된다.

: 쓰레드 생성후 메모리 구조는 해당 쓰레드만을 위한 스택을 생성할 뿐 그 이외의 영역은 프로세스영역을 공유하고 있다.

- 쓰레드의 특성 1 : 쓰레드마다 스택을 독립적으로 할당해 준다.

: 스택은 함수 호출 시 전달되는 인자, 되돌아갈 주소값 및 함수내에서 선언하는 변수들을 저장하는 메모리 공간이다.

: 실행흐름의 추가를 위한 최소 조건이다.

- 쓰레드의 특성 2 : 코드 영역을 공유한다.

: 프로세스의 main 함수 이외에도 쓰레드의 main 함수가 따로 존재한다.

- 쓰레드의 특성 3 : 데이터 영역과 힙을 공유한다.

: 쓰레드 간에 힙과 데이터 영역을 공유하기 때문에 IPC가 필요 없어졌다. 전역변수와 malloc 함수를 통해서 동적할당된 메모리 공간은 공유가 가능하다.

: 메모리 영역을 공유할 때 문제가 발생할 수 있기 때문에 프로그래밍시 주의가 필요하다

* Windows에서의 프로세스와 쓰레드

: Windows 입장에서는 프로세스는 단순히 쓰레드를 담는 상자에 지나지 않는다.

: 사실 Windows운영체제에서 프로세스는 상태를(Running, Ready, Blocked)를 지니지 않고 쓰레드가 가진다.

: 스케줄러가 실행단위로 잡는 것도 쓰레드이다.

: 즉, Windows에서 실행의 중심은 프로세스가 아니라 쓰레드이다.

: main Thread라고 부르며 일반적으로 프로그래머에 의해서 직접적으로 생성되는 쓰레드와 구분지어 말한다.

2. 쓰레드 구현 모델에 따른 구분

* 커널레벨(Kernel Level) 쓰레드와 유저레벨(User Level) 쓰레드

-. 커널레벨 쓰레드 모델

: 프로그래머 요청에 따라 쓰레드를 생성 및 스케줄링하는 주체가 커널인 경우, 커널 레벨 쓰레드라고 한다.

: 위의 유저영역은 코드, 데이터, 스팁 및 힙을 가리킨다.

: 커널 영역은 운영체제라는 하나의 소프트웨어를 실행시키기 우해서 필요한 메모리 공간이다.

: 오늘 날의 대부분의 운영체제는 커널 레벨 쓰레드를 기반으로 쓰레드 모델을 지원한다.

-. 유저레벨 쓰레드 모델

: 커널에서 쓰레드 기능을 지원하지 않을 때 생각해 볼 수 있는 모델.

: 커널에 의존적이지 않은 형태로 쓰레드의 기능을 제공하는 라이브러리를 활용할 수 있다.

: 쓰레드를 지원하지 않기 때문에 스케줄링의 대상은 프로세스이다.

: 쓰레드를 스케줄링하는 스케줄러는 유저영역에서 실행된다.

Tip 커널(Kernel) 영역

: 운영체제도 일반적 프로세스과 마찬가지로 함수, 스택, 코드, 전역함수 선언 등등이 동일하게 존재한다.

: 영역이 다른 프로그램일 뿐이고 유저가 사용하는 프로세스와 혼선을 피하기 위해 유저영역, 커널영역으로 나누어 둔것이다.

Tip 컨텍스트 스위칭이 빨라진 쓰레드

- pc : 쓰레드마다 별개의 main함수가 돌아가므로 Context switching이 발생한다.

- fp, sp : 스텍은 별도이므로 Context switching이 발생한다.

- Register : 공유될수는 있으나 디자인에 따라 달라지므로 일반적으로 언급하기 힘들다

- 성능의 차이는 Cash에서 찾자(한번 읽어들인 메인 메모리의 데이터를 저장하고 있다가 CPU가 다시 그 메모리에 저장된 데이터를 요구할 때, 바로 전달해주는 역할)

- 쓰레드는 Cash에 있는 정보를 같이 사용하기 때문에 Cash가 다시 메인 메모리를 읽어들일 필요가 사라진다.


* 커널 모드(Kernel Mode)와 유저모드(User Mode)

: 유저 모드에서는 커널 영역으로의 접근이 금지된다. 

: 커널 모드에서는 모든 영역의 접근이 혀용된다.

: 모드의 전환(커널 모드 유저모드)은 시스템에 부담을 주는 일이다.

: 커널 모드와 유저 모드를 제공하는 것은 프로세서(Processor), 즉 CPU에서 제공하는 일이다.

* 커널 레벨 쓰레드와 유저 레벨 쓰레드의 장점 및 단점

- 커널 레벨 쓰레드

장점 : 안전성, 기능의 다양성

단점 : 커널에서 기능을 제공하기 때문에 성능 저하

- 유저레벨 쓰레드

장점 : 전환 필요없기때문에 성능 좋음

단점 : 프로세스 내에 쓰레드가 하나만 블로킹 되어도 나머지 쓰레드가 작동하기 어려움

: 리눅스의 경우 유저 레벨 쓰레드를 활용하기도 한다.


뇌를 자극하는 윈도우즈 시스템 프로그래밍
국내도서
저자 : 윤성우
출판 : 한빛미디어 2007.03.30
상세보기


1. 프로세스의 이해

: 오늘날의 운영체제를  멀티 프로세스 운영체제 라고 부른다. 프로세스가 여러개 존재할 수 있는 운영체제라는 뜻이다.

: 프로세스는 무엇이고 프로세스라는 것이 여러개 존재할 수 있는것일까?    

* 프로세스란 무엇인가?

: 프로세스란 실행 중에 있는 프로그램을 의미한다

: 메모리 공간으로 올라간 프로그램이 프로세스라고 볼 수 있다.

* 프로세스를 구성하는 요소

- Execution of "C"Program

: 프로그램이 실행될 때 구성되는 메모리 공간

Data 영역 : 전역변수나 static 변수의 할당을 위함

Stack 영역 : 지역변수 할당과 함수 호출시 전달되는 인자값 저장

Heap 영역 : 동적할당(malloc, calloc 함수) 

Code 영역 : 실행파일을 구성하는 명령어들이 올라가는 메모리 영역

: 위의 사진은 프로세스 생성시 만들어지는 메모리 구조를 보여주고 있는데, 이 자체를 그냥 프로세스라고 표현하기도 한다.

: 명령어들이 올라와 있는 상태이고 필요한 메모리 공간이 할당되어 있는 상태이기 때문이다.

* Register Set

: 프로그램 실행을 위해서는 Register들이 절대적으로 필요하기 때문에, 프로세스를 구성하는 요소로 더불어 생각해보아야 한다.

: 그러므로 Register의 상태까지도 프로세스의 일부로 포함시켜 말할 수 있다.


2. 프로세스의 스케줄링과 상태 변화

: "CPU는 하나인데, 어떻게 여러개의 프로그램이 동시에 실행 가능한 것인가?"

* 프로세스의 스케줄링

: 하나의 CPU가 여러개의 프로세스를 번갈아 가면서 실행해야한다.

: CPU는 매우 빠르기 때문에 여러개의 프로그램을 고속으로 번걸아가면서 실행시킬 경우, 사용자는 동시에 여러개의 프로그램이 실행된다고 느껴진다.

- 스케줄링의 기본 원리

: 프로세스의 CPU 할당 순서 및 방법을 결정짓는 일을 가르켜 스케줄링이라 하며 이때 사용되는 알고리즘을 스케줄링 알고리즘이라고 한다.

: 이를 적용해서 프로세스를 관리하는 운영체제 요소(모듈)을 가리켜 스케쥴러라고 한다

- 멀티 프로세스는 CPU를 바쁘게 한다.

: A,B,C의 프로세스가 실행되는 형태

1. 고전적

: 순차적 실행방법 => A시작종료, B시작종료, C시작종료

2. 동시 실행

 : A,B,C를 모두 실행시키고 스케쥴러에 의해 프로세스들이 관리되도록 함

: 이 두가지 방법의 차이는 프로그램 특성에 따라 달라진다.

: 일반적으로 프로세스는 입력/출력 과정(인터넷에서 사이트를 다운받거나, 메모리에서 불러올 때)에서 시간이 많이 소요된다. 이떄 CPU는 아무일을 하지 않고 대기하게 된다.

: A프로세스가 I/O에 관련된 일을 할 때 B 프로세스가 CPU에 의해 실행된다면 얼마나 효율적일까?


* 프로세스의 상태 변화

: 프로세스 각각의 상태는 시간 흐름에 따라 변화한다.

상황 1. S(start)에서 Ready 상태로의 전이를 보여준다.

: 프로세스가 생성되고 Ready상태로 들어간다.

: CPU에 의해 실행되기를 기다린다.

상황 2. Ready 상태에서 Running 상태로의 전이를 보여준다.

: Ready 상태에 있는 프로세스들은 스케줄러에 의해 관리되는 프로세스들이다.

: 스케줄러는 Ready 상태에 있는 프로세스 중 하나를 알고리즘에 의해 선택해서 실행한다.

상황 3. Running 상태에서 Ready 상태로의 전이를 보여준다.

: 프로세스들은 생성시 중요도에 따라서 우선순위가 매겨진다.

: 우선수위가 높은 프로세스를 Ready에서 Running 상태로 끌어 올리고 종료 후 다른 프로세스를 실행한다.

상황 4. Running 상태에서 Blocked 상태로의 전이를 보여준다.

: 일반적으로 데이터 입.출력에 관한 일을 할때 발생된다

: 실행 중에 있는 프로세스가 실행을 멈추는 상태로 들어가게 된다.

: 대신 Ready 상태에 있는 프로세스 하나를 실행시켜  CPU를 효율적으로 사용한다.

상황 5. Blocked 상태에서 Ready 상태로의 전이를 보여준다

: Blocked 상태는 스케줄러에 의해서 선택될 수 없는 상태를 의미한다.

: 입출력이 완료되었을 때에 Ready 상태로 전이된다.

* 프로세스의 상태변화, 시나리오로 다시 이해하기

: 책 참고.

3. 컨텍스트 스위칭 (Context Switching)

: 멀티 프로세스 운영체제의 기본 원리에 대해서 이야기 했는데, 이는(실행 중인 프로세스의 변경) 사실 시스템에 많은 부하를 가져다 주기도한다.

"CPU 내에 존재하는 레지스터들은 현재 실행 중에 있는 프로세스 관련 데이터들로 채워진다"

: 따라서 프로세스가 변경될 떄에는 현재 레지스터들이 지니고 있는 데이터를 어딘가에 저장해야, 나중에 이전 프로세스를 실행했을 때 작업을 이어서 할 수 있다. 

: 새롭게 시작되는 프로세스도 이미 저장된 레지스터 데이터들이 있을 수 있으므로, 복원시켜주어야만 한다.

: 이 작업을 일컬어 Context Switching 이라고 한다.

: 레지스터 개수가 많은 시스템일 수록 이는 더 복잡해지며, 멀티 프로세스 운영체제의 단점이다.

: 즉, I/O 과정에서 발생하는 CPU손실과 Context Switching 과정에서 발생하는 손실을 비교하여 어느 것이 성능향상에 도움이 되는지 고려해야한다.

: 이는 프로그램마다 다르게 나타나므로, 감각을 키워나가야 한다.

4. 프로세스의 생성

* 프로세스의 생성

: 프로그램이 다른 프로그램을 실행시켜도 이는 프로세스가 생성된 것이므로, 다른 프로그램을 실행시키는 프로그램을 만들어보자.

* CreateProcess 함수의 이해

: Windows에서 프로세스 생성을 돕기 위해 제공하는 함수이다.

: 새로운 프로세스간에 부모-자식 프로세스 관계가 형성된다.

* 예제를 통한 CreateProcess 함수의 이해


뇌를 자극하는 윈도우즈 시스템 프로그래밍
국내도서
저자 : 윤성우
출판 : 한빛미디어 2007.03.30
상세보기


+ Recent posts