Thread란
하나의 프로그램내에서 여러 개의 실행 흐름을 두기 위한 모델
하나의 프로세서(실행 중인 프로그램)에서 각 독립적인 일의 단위인 스레드(Thread)로 여러 작업을 처리할 수 있다. 즉 하나의 프로세서에서 병렬적으로 여러 개 작업을 처리하기 위해서는 각 작업을 스레드화하여 멀티스레딩이 가능하게 해야 한다.
Process란
간단하게 말하면 실행중인 프로그램.
프로세스는 사용 중인 파일, 데이터, 프로세서의 상태, 메모리 영역 주소 공간, 스레드 정보, 전역 데이터가 저장된 메모리 부분 등 수 많은 자원을 포함하는 개념. 종종 스케쥴링의 대상이 되는 작업이라고 불리기도 함
쓰레드와 프로세스의 차이점
프로세스는 완벽히 독립적이기 때문에 메모리 영역(Code, Data, Heap, Stack)을 다른 프로세스와 공유를 하지 않지만, 쓰레드는 해당 쓰레드를 위한 스택을 생성할 뿐 그 이외의 Code, Data, Heap영역을 공유한다.
텍스트 : PC(피시 카운터 - 다음번에 실행 될 명령어의 주소를 가지고 있는 레지스터), 프로그램 코드 저장
데이터: 글로벌 변수, 스태틱 변수 저장
힙 :메모리관리, 동적 메모리 할당(시스템 콜로 관리)
스택: 임시 데이터 저장- 로컬 변수, 리턴 어드레스
스택을 독립적으로 할당하는 이유
- 스택은 함수 호출 시 전달되는 인자, 되돌아갈 주소값 및 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간이다. 따라서 스택 메모리 공간이 독립적이라는 것은 독립적인 함수 호출이 가능하다는 것이고, 이는 독립적인 실행 흐름이 추가되는 것이다. 결과적으로 실행 흐름의 추가를 위한 최소 조건이 독립된 스택을 제공하는 것이다.
코드 영역을 공유
- 프로세스는 독립적인 구조이기 때문에 다른 프로세스의 Code영역에 있는 함수를 호출할 수 없다.
- 쓰레드는 Code영역을 공유하기 때문에 두 개 이상의 쓰레드가 자신이 포함된 프로세스의 Code영역에 있는 함수를 호출할 수 있다.
데이터 영역과 힙 영역을 공유
- 전역 변수와 동적 할당된 메모리 공간을 공유할 수 있고, 이를 통해 쓰레드 간 통신을 할 수 있지만 동시에 메모리에 접근하기 때문에 주의해야 한다.
멀티 프로세스의 문제점
- 두 개의 프로세스는 완전히 독립된 두 개의 프로그램 실행을 위해서 사용되기 때문에 컨텍스트 스위칭(프로세스의 상태 정보를 저장하고 복원하는 일련의 과정)으로 인한 성능 저하가 발생
- 쓰레드는 하나의 프로그램 내에서 여러 개의 실행 흐름을 두기 위한 모델이다.
- 쓰레드는 프로세스처럼 완벽히 독립적인 구조가 아니다. 쓰레드들 사이에는 공유하는 요소가 있다.
- 쓰레드는 이 공유하는 요소로 인해 컨텍스트 스위칭에 걸리는 시간이 프로세스보다 짧다.
쓰레드가 프로세스보다 컨텍스트 스위칭이 빠른 이유
쓰레드가 프로세스보다 컨텍스트 스위칭이 빠른 이유는 메모리 영역을 공유하기 때문이다. 실제로 공유되는 데이터가 있고 아닌 데이터가 있다.
sp(Stack Pointer), fp(Frame Pointer), pc(Program Counter) 레지스터
- pc는 실행해야 할 명령어의 위치를 가리키는 레지스터이다.
- 쓰레드별로 main함수를 독립적으로 가지고 있고, 함수 호출도 독립적으로 진행되기 때문에 쓰레드별로 현재 pc값은 달라야 한다. 따라서 pc는 공유되지 않는다.
- 쓰레드는 독립적인 스택을 가지기 때문에 스택의 정보를 담고 있는 sp와 fp는 공유되지 않는다.
범용적으로 사용가능한 레지스터
- 시스템을 어떻게 디자인 하느냐에 따라 달라지는 것이기 때문에 일반적으로 공유된다고 할 수 없다.
캐시메모리
- 캐시 메모리는 CPU에서 한번 이상 읽어 들인 메인 메모리의 데이터를 저장하고 있다가 CPU가 다시 그 메모리에 저장된 데이터를 요구할 때 메인 메모리를 통하지 않고 바로 값을 전달하는 용도로 사용된다.
- 프로세스 사이에서 공유하는 메모리가 하나도 없기 때문에 컨텍스트 스위칭이 발생하면 캐쉬에 있는 모든 데이터를 모두 리셋하고 다시 캐쉬 정보를 불러와야 한다.
- 쓰레드는 캐쉬 정보를 비울 필요가 없기 때문에 프로세스와 쓰레드의 컨텍스트 스위칭 속도의 차이는 이때 발생한다.
Windows에서의 프로세스와 쓰레드
- Windows 입장에서 프로세스는 쓰레드를 담는 상자에 지나지 않는다.
- 또한 Windows에서 프로세스는 상태(Running, Ready, Blocked)을 지니지 않는다. 상태를 지니는 것은 스레드이다.
- 스케줄러가 실행의 단위로 선택하는 것도 프로세스가 아닌 스레드이다.
- 프로세스 컨텍스트 스위칭 역시 실제로 오버헤드가 발생하는 부분은 서로 다른 프로세스에 포함된 스레드 간의 컨텍스트 스위칭시 발생한다.
[OS]메모리 관점에서 본 쓰레드(thread)
메모리 관점에서 본 process의 특징
각각의 프로세스는 메모리 공간에서 독립적으로 존재한다.
<출처:https://elgaabeb.wordpress.com/>
전에 본 적이 있는 그림이다. 이 그림은 프로세스를 구성하는 메모리 공간의 모습이다. 각각의 프로세스는 자신만의 이런 메모리 구조를 가진다. 프로세스A, B, C가 존재한다면 각각 프로세스는 모두 위와 같은 구조의 메모리 공간을 가진다.
독립적인만큼 다른 프로세스의 메모리 공간에 접근할 수도 없다. A가 B의 메모리 공간에 접근하면 재앙이 발생할 수도 있다. 만약 A가 뜬끔없이 Chrome의 메모리 공간에 접근한다고 생각해보라. Chrome의 안정성이 보장될 수 있겠는가? 더 뜬금없이 A가 windows의 메모리 공간에 접근한다고 생각해보라. 운영체제의 메모리 공간에 접근하여 뭔가를 변경한다면 심각한 문제가 발생할 수 있다.(물론 운영체제의 메모리 공간에 접근하는 것은 원천적으로 불가능하다) 그러므로 프로세스의 안정성을 보장하기 위해서는 프로세스는 각각 독립된 메모리 공간을 가져야 한다.
그러면 혹시 A에서 연산한 결과를 B에서 받아서 사용하고 싶다면 어떻게 해야할까?
IPC(inter process communication)
<출처: http://madhusudhanrc.blogspot.kr/2012/08/inter-process-communicationipc.html>
A의 메모리 공간에 B가 직접 접근하지 못하기 때문에 프로세스간의 통신을 하는 특별한 방법들이 존재한다. 메일슬롯(mailslot), 파이프(pipe) 등이 바로 프로세스 간의 통신 즉, IPC의 예들이다.
IPC에 대한 자세한 설명은 생략~
중요한 점은 프로세스는 독립적인 메모리 공간을 지니기 때문에 IPC를 통하지 않고는 통신할 수 없다는 사실이다. 그리고 프로세스가 여럿이 병렬적으로 실행되기 위해서는 필연적으로 컨텍스트 스위칭이 발생할 수 밖에 없다.
프로세스가 지니는 제한
독립적인 메모리 공간으로 컨텍스트 스위칭이 발생한다.
통신하기 위해서는 IPC가 필요하다.
이 두 가지 문제점을 한 번에 해결할 수 있는 녀석이 쓰레드이다.
쓰레드
쓰레드(thread)는 하나의 프로그램 내에 존재하는 여러 개의 실행 흐름을 위한 모델이다. 우리가 생각하는 프로그램이 실행되기 위해서 하나의 실행흐름으로 처리할 수도 있지만 다수의 실행흐롬으로 처리할 수도 있다.(multi-thread)
다시 말해서 프로세스에 존재하는, 프로세스가 실행되는 흐름이다.
<출처: http://en.wikipedia.org/wiki/Thread_(computing)>
wikipedia를 보면 쓰레드를 설명하기 위해 위와 같은 그림들을 보여준다. 아래 그림을 보면 프로세스 내부에 2개의 쓰레드가 존재한다. 그리고 시간의 방향을 따라 쓰레드가 실행되고 있다. 그림에서 볼 수 있듯이 쓰레드는 프로세스와 별개가 아닌 프로세스를 구성하고 실행하는 흐름이다.
프로세스에서도 그러했듯이 이번에도 메모리 관점에서 쓰레드를 보자. 프로세스와 어떤 차이가 있는지 뚜렷하게 알 수 있을 것이다.
메모리 공간에서의 쓰레드
<출처: http://www-01.ibm.com/support/knowledgecenter/SSLTBW_1.12.0/com.ibm.zos.r12.euvmo00/euva3a00451.htm>
위 그림은 프로세스와 쓰레드의 메모리 구조의 차이점을 보여준다. 왼쪽의 프로세스는 이미 봤기 때문에 설명하지 않고, 오른쪽의 thread에 주목하자. 앞서 말한 것처럼 쓰레드는 프로세스 안에 존재하는 실행흐름이다. 메모리 구조 역시 그러하다. 하지만 특이한 점은 쓰레드는 프로세스의 heap, static, code 영역 등을 공유한다는 사실이다. 각각의 프로세스가 독립적인 stack, heap, code, data 영역을 가진 반면에, 한 프로세스에 속한 쓰레드는 stack 영역을 제외한 메모리 영역은 공유한다.
//첨언 : 쓰레드는 stack 뿐만 아니라 레지스터또한 독립적인 공간이다
//굳이 중요도를 따지자면 레지스터의 독립적인 공간에 좀 더 관심을 둘 필요가 있다
쓰레드가 code 영역을 하기 때문에 한 프로세스 내부의 쓰레드들은 프로세스 가 가지고 있는 함수를 자연스럽게 모두 호출할 수 있다.
뿐만 아니라 쓰레드는 data, heap 영역을 공유하기 때문에 IPC 없이도 쓰레드 간의 통신이 가능하다. 동일한 프로세스 내부에 존재하는 쓰레드 A, B가 통신하기 위해 heap 영역에 메모리 공간을 할당하고, 두 쓰레드가 자유롭게 접근한다고 생각하면 된다.
쓰레드는 프로세스처럼 스케줄링의 대상이다. 이 과정에서 컨텍스트 스위칭이 발생한다. 하지만 쓰레드는 공유하고 있는 메모리 영역 덕분에 컨텍스트 스위칭 때문에 발생하는 오버헤드(overhead)가 프로세스에 비해 작다.
ref : http://brownbears.tistory.com/39
ref : https://mooneegee.blogspot.com/2015/01/os-thread.html
반응형
'운영체제 & 병렬처리 > Multithread' 카테고리의 다른 글
[2] #include <thread> std::thread t(HelloThread); (0) | 2022.09.06 |
---|---|
[1] 물리적인 쓰레드와 논리적인 쓰레드의 이해 (0) | 2022.09.05 |
Reentrant 와 Thread-safe 의 차이 (0) | 2015.12.16 |
error C2719: 'size': __declspec(align('16'))를 사용하는 정식 매개 변수는 정렬되지 않습니다. (0) | 2013.05.11 |
Window에서 최대한 Realtime을 지켜보자& multi-thread (1) | 2013.02.02 |