티스토리 뷰

결론부터 얘기하면 동기화를 제공하기 위해선 Lock, 세마포어, 모니터 등의 방법을 사용 할 수 있으나 Lock을 사용하는 방식엔 문제가 있다.


여러개의 프로세스가 하나의 공유자원에 동시에 접근하게 될 경우 공유 자원의 값이 꼬이는 현상이 발생 할 수 있는데 이것을 race condition(경쟁 상태)이라고 한다. 


동기화라는것은 내가 알고 있는 정보와 니가 알고 있는 정보가 일치해야 한다는것이다. 프로세스의 관점에서 보면 프로세스 A와 B가 있을때 서로가 알고 있는 공유자원의 값이 같아야 한다는것이다. 공유 자원에 접근하는 코드 영역을 Critical Section(임계 영역)이라고 하는데, 이 임계영역에 프로세스가 동시에 접근하게 되면 경쟁 상태가 발생하는 것이다.


그러므로 동기화( 프로세스 A,B가 알고 있는 공유자원의 값이 일치해야 함)를 위해서는 크리티컬 섹션에 동시에 두개의 프로세스가 실행되서는 안된다. 


즉, 임계영역에 한번에 하나의 프로세스만 입장시켜야 하는것을 동기화, 상호배제라고 한다.

상호배제 = 서로 배제시킨다 = 한번에 하나만 들어갈 수 있다.


동기화를 구현하는 방법은 다양하다. 우선 lock이라는 것을 통해서 구현 할 수 있다.


lock이란 boolean변수이며 true, false값을 갖는다. 공유 자원에 접근할 수 있으면 lock = false인 상태이고 접근할 수 없으면 lock= true인 상태일 것이다.


while(lock == true); //무한 대기 busy waiting

lock = true;

//

크리티컬 섹션 (공유 자원에 접근하는 코드 영역)

//

lock = false;

락을 통해 동기화를 제공하는 코드는 위와 같다. 

즉, lock == true인 상태(화장실이 누군가에 의해 사용중이다)에서는 while문에서 계속 무한 반복상태로 대기한다. 그러다가 lock == false가 된순간(임계영역에 들어갈 수 있는 권한을 얻은 순간, 화장실이 비어있다고 확인한것과 동일) 내가 임계영역을 사용할것이므로 lock=true로 설정하고(내가 화장실을 사용중이다라고 표시) 임계영역을 사용한다음 다시 lock=false(화장실이 비어있다고 표시)로 만듦으로써 다른 프로세스가 임계영역에 지원할 수 있게끔 하는 것이다.


근데 이런 lock을 통한 동기화 방식에는 문제가 있다.

1. 화장실이 비어있다고 판단하는 행위 while(lock==true);

2,. 화장실을 내가 사용중이라고 표시하는 행위 lock = true;

이 두개가 동시에 일어나지 않는다.(원자적으로 일어나지 않으며 쪼개질 수 있다.) 


이런 상황을 생각해보자.

프로세스 A가 1번을 실행한 상태에서 스케쥴링이 일어나서 프로세스B가 1,2번을 실행하고 그 다음 프로세스 A의 2번이 실행됬다.

프로세스 A는 현재 화장실이 비어있다고 판단한 상태에서 일시 정지 당했다. 일시 정지가 풀리면 이 친구는 바로 임계 영역에 입장 할 것이다.


프로세스 B는 화장실이 비어있어서 사용중이라고 표시한다음 화장실을 사용하려 하고 있다. 이때 다시 스케쥴링이 일어나서

A의 블락이 풀리는 순간 lock = true로 설정하고 화장실에 입장한다. 즉, 2개의 프로세스가 동시에 화장실(공유자원)에 입장해 버린 것이다.


이것은 상호배제, 동기화가 이뤄 지지 않은 케이스이다. 이런 문제는 100번 실행중 100번 모두 나타나지 않기 때문에 버그 잡기가 힘들다. 이것이 발생한 원인은 화장실이 비어있는지 확인 하는 1번 행위와 화장실을 사용중이라고 표시하는 행위인 2번이 따로따로 일어나기 때문이다. 저 행위는 원자적 단위로 일어나야 한다. 1번 수행 후 2번이 실행되기 전에 스케쥴링이 일어나면 안된다는 말이다. 그것을 하드웨어적으로 제공하는것이 testandset메소드이다. 뭐 이런 해결책들이 있지만 어쨌든 LOCK만을 통해서는 제대로된 동기화를 제공 할 수 없다.


그래서 나온것이 세마포어(신호등이란뜻)이다.

세마포어는 두가지 연산으로 이루어져 있으며 값을 갖는 추상 자료형이다.

위에서는 화장실이 비었는지 내가 직접 무한 반복 방식으로 확인했지만 이 세마포어를 사용하면 사용이 끝난 프로세스가 대기중인 프로세스에게 사용이 끝났다고 알려준다. 그래서 CPU낭비가 줄어드는 아주 좋은 방식이다.


세마포어는 up, down 2가지 연산이 있는데 

up연산은 값을 하나 증가 시키고 잠들어 있는 프로세스가 있다면 깨운다. 또한, 공유 자원이 가득 차면 프로세스를 잠재운다.

down연산은 값을 하나 감소 시키되 공유 자원이 비면 프로세스를 잠재운다.


이진 세마포어(mutex), 카운팅 세마포어와 같이 여러 종류의 세마포어가 존재한다. 임계 영역을 세마포어의 down, up 순서로 감싸게 되면 동기화를 제공할 수 있지만 이것도 문제가 있다.


사용자가 실수 할 여지가 충분하다는 것이다. 예를 들어, down을 한다음에 또 실수로 down을 한다던지 up&up을 한다던지 등의 문제가 발생할 수 있다. 정확히 쓰면 문제가 생기지 않지만 멀티 쓰레드, 멀티 프로세싱 환경에서 이런 실수는 잘 발견 되지 않기 때문에 개발자의 실수를 줄여줄만한 다른 방법이 필요하다.


그래서 나온것이 모니터이다.

모니터란 공유 자원을 내부적으로 갖고 있으며 외부에 공개되지 않는다. 마치 클래스에서 private변수와 비슷하다.

그리고 public 메소드를 통해서만 공유 자원에 접근 할 수 있다. 또한, 모니터에는 한번에 하나의 프로세스만 입장할 수 있다.


이런 방식으로 상호배제, 동기화를 제공하고 있는 것이 모니터이다.







'컴퓨터 공학과 졸업 > 운영체제' 카테고리의 다른 글

메모리 관리 기법 - 2  (0) 2018.10.26
메모리 관리 기법 - 1  (0) 2018.10.25
스케쥴링 알고리즘  (0) 2018.10.17
식사하는 철학자 문제 요약  (0) 2018.08.10
busy waiting  (0) 2018.08.10
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함