컨텍스트 스위칭

(Context Switching)




컨텍스트 스위칭(Context Switching)이 무엇일까요? 우리가 전에 보았던 '시스템 프로그래밍: 프로세스 스케줄링(Process Scheduling)'이라는 글에서 프로세스는 총 5개의 상태로 구분할 수 있다고 말했었습니다. 그 중에서 준비(Ready) 상태인 프로세스들 중에서 스케줄러의 선택을 받은 하나의 프로세스가 실행 중(Running) 상태로 상태가 전이됩니다. 

컨텍스트 스위칭(Context Switching)

예를 들어서, Ready 상태인 A 프로세스와 Running 상태인 B 프로세스가 있고 인터럽트 요청에 의해 서로 상태가 전이된다고 가정합니다. 이 때, A 프로세스가 Ready 상태로 전이되고, B 프로세스가 Running 상태가 될 때 A 프로세스의 상태 또는 레지스터 값 등이 PCB(Process Control Block)에 저장되고, A 프로세스의 정보를 PCB에서 CPU로 적재시킵니다.


● PCB(프로세스 제어 블록: Process Control Block): PCB에는 프로세스 상태 또는 레지스터의 값 등과 같은 관련 데이터들이 저장됩니다. 프로세스 생성 시 만들어지며, 프로세스마다 고유한 PCB를 가집니다.


간단하게 말해서, 컨텍스트 스위칭은 위에서 가정했듯이, Ready 상태인 A 프로세스가 존재하고, Running 상태인 B 프로세스가 존재하는데 인터럽트 요청에 의해 서로 상태가 전이되는 상황을 생각해봅시다. 


CPU 내의 레지스터들(Register Set)에는 현재 실행중인 프로세스의 관련 데이터들이 들어가는데, B 프로세스가 Ready 상태가 되면 현재 레지스터에 저장된 A 프로세스의 데이터들을 메모리 공간에 저장해두고, B 프로세스의 레지스터 값을 메모리에서 CPU로 적재합니다. 그런데 이 컨텍스트 스위칭이 일어나는 동안 CPU는 아무런 일을 하지 못하며, 컨텍스트 스위칭은 CPU에 많은 부하를 가져다 줍니다. 이는 멀티 프로세스 운영체제의 단점이며, 이러한 컨텍스트 스위칭의 시간은 레지스터의 수나 메모리의 속도 등에 좌우됩니다.



출처: http://blog.eairship.kr/257 [누구나가 다 이해할 수 있는 프로그래밍 첫걸음]

'OS' 카테고리의 다른 글

OS 학습 참고  (0) 2018.08.08
메모리 관점에서 본 쓰레드(thread)  (0) 2018.08.08
쓰레디와 임계영역  (0) 2018.08.08
세마포어 뮤텍스  (0) 2018.08.08

http://talkingaboutme.tistory.com/549?category=608888        OS 학습

'OS' 카테고리의 다른 글

컨텍스트 스위칭  (0) 2018.08.08
메모리 관점에서 본 쓰레드(thread)  (0) 2018.08.08
쓰레디와 임계영역  (0) 2018.08.08
세마포어 뮤텍스  (0) 2018.08.08

[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 영역을 제외한 메모리 영역은 공유한다. 

 쓰레드가 code 영역을 하기 때문에 한 프로세스 내부의 쓰레드들은 프로세스 가 가지고 있는 함수를 자연스럽게 모두 호출할 수 있다.

 뿐만 아니라 쓰레드는 data, heap 영역을 공유하기 때문에 IPC 없이도 쓰레드 간의 통신이 가능하다. 동일한 프로세스 내부에 존재하는 쓰레드 A, B가 통신하기 위해 heap 영역에 메모리 공간을 할당하고, 두 쓰레드가 자유롭게 접근한다고 생각하면 된다.

 쓰레드는 프로세스처럼 스케줄링의 대상이다. 이 과정에서 컨텍스트 스위칭이 발생한다. 하지만 쓰레드는 공유하고 있는 메모리 영역 덕분에 컨텍스트 스위칭 때문에 발생하는 오버헤드(overhead)가 프로세스에 비해 작다. 


https://mooneegee.blogspot.com/2015/01/


'OS' 카테고리의 다른 글

컨텍스트 스위칭  (0) 2018.08.08
OS 학습 참고  (0) 2018.08.08
쓰레디와 임계영역  (0) 2018.08.08
세마포어 뮤텍스  (0) 2018.08.08

2015. 1. 26.

[OS]쓰레드(Thread)와 Critical Section(임계영역)

 
 쓰레드에 대한 기본적인 지식을 바탕으로 쓰레드의 특성에 대해 좀더 살펴보고자 한다. 메모리 관점에서 본 쓰레드에 대한 지식이 있다면 이해하기 편할 것이다.


프로세스와 메인 쓰레드(main thread)

  쓰레드는 프로세스에 존재하는 실행 흐름 중 하나이다. 그런 실행 흐름 중에는 우리가 흔히 main() 함수라고 부르는 쓰레드가 존재한다. 어떤 프로그램을 실행시키면 main() 함수가 실행되는데, 이는 다시 말해 main 쓰레드가 실행된다는 것을 의미한다.  만약 main 쓰레드를 통해서 다른 쓰레드를 만들어서 다른 쓰레드로 하여금 특정한 일을 시키면 어떨까? 이 상황은 아래의 그림과 같다.(쓰레드의 의미 중에 실, 가닥이라는 의미도 있다)

 
<출처: http://www.onlinebuff.com/article_understand-threading-and-types-of-threading-in-c-using-an-example_56.html>

 
 main 쓰레드는 프로세스가 실행되면 자동적으로 실행되는 thread이다. 그림에 등장하는 worker 쓰레드는 main 쓰레드가 생성한 새로운 쓰레드이다. 새로운 worker 쓰레드는 main 쓰레드와는 별개로 자신의 고유한 작업 흐름을 가진다.

 
 그런데 메모리 관점에서 본 쓰레드를 떠올려 보면 쓰레드는 heap, data 영역을 공유한다는 것을 알 수 있다. 고유한 작업 흐름을 가지는데 메모리를 공유한다는 점에 주목해야 한다.


 
 
쓰레드를 사용하여 실행흐름을 분할 

 
 만약 어떤 사람이 0 ~ 100,000 사이의 숫자의 총합을 구하고자 한다. 이 사람은 thread의 대한 지식을 가지고 있었다. 이 사람은 0 ~ 33,333까지의 합을 thread1로 처리하고, 33,334 ~ 66,666까지의 합은 thread2로 처리하고, 66,667 ~ 100,000가지의 합은 thread3으로 처리해야겠다고 생각하였다. 하나의 thread로 0 ~ 100,000까지의 합을 구하는 것보다는 실행흐름을 3개로 나누고, 3개의 실행 흐름을 병렬적으로 수행하면 합을 구하는 시간이 줄어들 것으로 예상한 것이다. 얼핏 들으면 매우 그럴듯한 발상이다. 하지만 이를 그대로 코드로 옮기면 문제가 발생한다.


 ThreadProc() 함수 바로 앞에 선언된 total은 static 변수이다. static 변수는 메모리의 data 영역에 존재하고, thread는 이를 공유하게 된다. 결국 3개의 쓰레드는 모두 static 변수 total에 접근가능하다. 이런 특성때문에 쓰레드는 IPC와 같은 방법으로 통신할 필요가 없다.

 하지만 위 total 변수는 쓰레드의 동시접근 문제를 발생시킬 수 있다.

 쓰레드는 결국 스케줄러에 의해 번갈아가며 실행된다. 이 과정에서 컨텍스트 스위칭은 불가피하게 발생한다. 프로세스는 독립적인 메모리 공간을 가지기 때문에 컨텍스트 스위칭 과정에서 데이터가 변경되지는 않는다. 하지만 쓰레드 간의 컨텍스트 스위칭은 상황이 다르다. 컨텍스트 스위칭 상황에서 쓰레드는 프로그램 라인 단위로 이뤄지지 않는다. 예를 들어 A() 함수가 실행 중 일 때는 절대 컨텍스트 스위칭이 발생하지 않는다고 생각하면 안 된다. 실행 중인 쓰레드의 변경은 매우 빈번하게 발생하며, 우리가 이에 쓰레드의 실행 흐름을 예측해서 제어하는 것은 불가능하다.

 그래서 둘 이상의 쓰레드가 위의 total과 같이 같은 메모리 영역을 동시에 참조하면 문제를 일으킬 수 있다. 우리는 덧셈이 올바르게 완료될 것으로 예상하지만, 이는 우리의 기대일 뿐이다. 1 + 2의 값을 3이라고 저장하지도 못한 상태에서 33,334 + 33,335를 계산하는 쓰레드가 실행될지도 모른다. 이렇게 되면 결국 total의 값은 3만큼 누락된다.


임계영역(Critical Section)

 위 코드의 worker 쓰레드 함수 내부의 total을 둘 이상의 쓰레드가 동시에 실행할 경우 문제가 발생할 수 있다. 이런 문제를 일으킬 수 있는 코드 블럭을 임계영역이라고 한다. 다시 말해 임계영역은 배타적 접근(한 순간에 하나의 쓰레드만 접근)이 요구되는 공유 리소스(전역변수, static 변수 등)에 접근하는 코드 블럭을 의미한다.
 
출처 : https://mooneegee.blogspot.com/2015/01/

 

'OS' 카테고리의 다른 글

컨텍스트 스위칭  (0) 2018.08.08
OS 학습 참고  (0) 2018.08.08
메모리 관점에서 본 쓰레드(thread)  (0) 2018.08.08
세마포어 뮤텍스  (0) 2018.08.08

여러 쓰레드들은 자원을 공유하고, 프로세스간 메시지를 전송하면서 간혹 문제가 발생할 수 있습니다.

 

즉, 공유된 자원에 여러 프로세스 , 쓰레드가 동시에 접근하면서 문제가 발생합니다. 

공유된 자원 속 하나의 데이터는 한번에 하나의 프로세스만 접근할 수 있도록 제한해 두어야 할 필요성이 있는데

이를 위해 고안된 것이 Semaphore(세마포어)입니다.

 

유명한 화장실 예제로 쉽게 설명해보겠습니다.

 

공중 화장실은 한번에 1명만 사용할 수 있다고 가정하겠습니다.

어떤 사람이 사용하고 있는데 다른 누군가가 갑자기 들어와서 같이 쓰자고 하면... 생각만해도 이상하지요..?

이를 막기 위해 화장실 열쇠를 만들 수 있습니다.

열쇠를 가지고 있는 한 사람만 화장실을 이용하고, 열쇠가 없는 사람은 밖에서 대기를 하죠.

 

여기서 열쇠는 세마포어와 같은 역할을 한다고 할 수 있습니다.

 

그럼 세마포터와 뮤텍스 각각 어떤 의미를 가지고 있을까요?

 

 

Semaphore(세마포어)

 

공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는 것!

 

그리고 세마포어는 리소스의 상태를 나타내는 간단한 카운터라고 할 수 있습니다.

일반적으로 비교적 긴 시간을 확보하는 리소스에 대해 이용하게 되며, 유닉스 시스템의 프로그래밍에서 세마포어는 운영체제의 리소스를 경쟁적으로 사용하는

다중 프로세스에서 행동을 조정하거나 또는 동기화 시키는 기술입니다.

 

위 화장실 예제로 다시 살펴보면, 세마포어는 1개 이상의 열쇠라고 할 수 있습니다.

만약 화장실 칸이 4개이고 열쇠가 4개라면, 4명까지는 대기없이 바로 사용할 수 있고 

그 다음 부터는 대기를 해야하죠. 이것이 바로 세마포어입니다.

 

그러므로 몇개의 세마포어로 구성해서 운영체제의 리소스를 경쟁적으로 사용할지는 꽤 중요한 이슈입니다.

그림으로 표현하면 아래와 같습니다.

 

 

Mutex(뮤텍스, 상호배제)

 

공유된 자원의 데이터를 여러 쓰레드가 접근하는 것을 막는 것!

 

즉, *Critical Section을 가진 쓰레드들의 Running tme이 서로 겹치지 않게 각각 단독으로 실행되게 하는 기술입니다. 

다중 프로세스들이 공유 리소스에 대한 접근을 조율하기 위해 locking과 unlocking을 사용합니다.

 

간단히 말해, Mutex객체를 두 쓰레드가 동시에 사용할 수 없다는 말입니다.

 

위 화장실 예제로 다시 살펴보면, 뮤텍스는 무조건 1개의 열쇠만 가질 수 있습니다!

 

그림으로 표현하면 아래와 같습니다.

 

 

 

*Critical Section

 

다중 프로그래밍 운영체제에서 여러 프로세스가 데이터를 공유하면서 수행될 때,

각 프로세스에서 공유데이터를 엑세스하는 프로그램 코드부분을 말합니다.

 

공유데이터를 여러 프로세스가 동시에 엑세스하면 시간적인 차이 때문에 잘못된 결과를 만들수 있습니다.

이를 막기 위해 한 프로세스가 위험부분을 수행하고 있을 때, 즉 공유데이터를 액세스하고 있을 때는 

다른 프로세스들은 절대로 그 데이터를 접근할 수 없도록 해야합니다. 

 

 

세마포어와 뮤텍스의 차이?

 

세마포어는 뮤텍스가 될수 있지만, 뮤텍스는 세마포어가 될 수 없습니다.

 

뮤텍스는 항상 열쇠 1개이고, 세마포어는 여러개 가질 수 있기 때문에 

세마포어의 열쇠가 1개라면 뮤텍스와 같습니다.

 

마포어는 파일시스템 상 파일형태로 존재, 뮤텍스는 프로세스 범위입니다.

즉, 프로세스가 사라질 때 뮤텍스는 clean up 됩니다.

 

세마포어는 소유할 수 없는 반면, 뮤텍스는 소유할 수 있습니다.

 

뮤텍스의 경우, 뮤텍스를 소유하고 있는 쓰레드가 이 뮤텍스를 해제할 수 있습니다.

반면, 세마포어의 경우, 세마포어를 소유하고 있지 않은 쓰레드도 이 세마포어를 해제할 수 있습니다.

 

 

출처 : http://sycho-lego.tistory.com/11

'OS' 카테고리의 다른 글

컨텍스트 스위칭  (0) 2018.08.08
OS 학습 참고  (0) 2018.08.08
메모리 관점에서 본 쓰레드(thread)  (0) 2018.08.08
쓰레디와 임계영역  (0) 2018.08.08

+ Recent posts