본문 바로가기
운영체제

운영체제 10장 - 프로세스 관리(7) : 읽기-쓰기 문제, 식사하는 철학자 문제 -

by ChocoPeanut 2017. 4. 22.

운영체제 10

- 프로세스 관리(7) : 읽기-쓰기 문제, 식사하는 철학자 문제 -

 

읽기 쓰기 문제는 공통 데이터베이스에 접근하는 문제를 다룬다. 서버에 데이터베이스가 존재하는데 다른 로컬 컴퓨터들이 데이터에 접근을 할 수 있다. 접근하는 사용자 중에는 ReaderWriter가 존재한다. Reader는 데이터를 읽기만 하는 사용자이고 Writer는 데이터를 읽고 수정할 수 있는 사용자를 의미한다. 데이터베이스를 사용자들이 모두 공통 사용하므로 임계구역이라고 생각할 수 있다.


우리는 앞의 임계구역 문제를 해결하기 위해 동기화를 사용하였는데 상호배타를 만족시키기 만들어 한 번에 한 개의 프로세스만 접근이 가능하게 만들었다. 임계구역에 데이터를 접근하는 사용자에 접근 권한을 두어 동시에 접근을 할 수 없게 만들었다. 하지만 위의 읽기 쓰기 예시를 한 번 살펴보면 이런 점이 매우 비효율적이라는 것을 알 수 있다.


만약 사용자 Reader1이 데이터베이스에 접근을 했는데 다른 Reader2가 데이터베이스에 접근을 한다고 문제가 발생할까? Reader는 데이터를 읽기만 하는 사용자를 의미한다. 따라서 데이터베이스에 접근을 하더라도 데이터의 변형을 만들지 않아 문제를 발생시키지 않는다. 효율성의 제고를 통해 Reader이 동시에 접근하려고 하면 접근 권한을 주어도 된다. 그러면 Writer의 경우는 어떨까? Writer는 데이터를 읽기도 하지만 쓰기도 한다. 즉 데이터의 변형, 업데이트가 일어난다. 따라서 Writer 두 사용자가 동시에 접근하면 문제가 발생할 수 있다. 그러면 Reader가 들어왔는데 Writer가 접근을 하고 싶어 하면 어떻게 될까? Reader가 읽고 있는 데이터가 Writer에 의해 변형, 업데이트 되므로 문제가 발생할 수 있다. Reader는 제대로 된 데이터를 읽을 수 없기 때문이다.



그러면 어떻게 설계를 해야 할까?


Reader가 데이터베이스(임계구역) 들어갈 경우, 다른 Reader는 접근할 수 있으나 Writer는 접근할 수 없다.

Writer가 데이터베이스(임계구역) 들어갈 경우, ReaderWriter 모두 접근할 수 없다.

 

위의 문제를 해결하기 위해서는 우선순위를 이용하여 해결할 수 있다. Reader에게 먼저 우선권을 주어 Reader가 접근을 하면 Writer는 반드시 다음으로 실행이 되어야한다.

 

식사하는 철학자 문제5명의 철학자가 식사를 하고 있는 상황을 가정한 문제이다. 철학자들이 원형의 테이블에 앉아 있는데 철학자들 사이에는 젓가락이 놓여있다. 하지만 젓가락이 한 쌍이 놓여 있는 게 아니라 하나가 놓여있는 상황이다. 철학자는 생각을 하면서 산다. 그러다가 배가 고프면 자신의 양 옆에 있는 젓가락을 사용해서 식사를 하고 또 다시 생각을 한다. 이러한 상황을 가정한 문제가 식사하는 철학자 문제이다. 여기서 어떤 문제가 발생하겠는가? 만약 서로 양 옆에 앉아 있는 철학자 같이 배가 고플 경우 어떻게 되겠는가? 식사하기 위해서는 젓가락을 두 개를 사용해야하는데 한 철학자가 사용할 경우 옆에 앉은 두 명의 철학자는 젓가락을 두 개를 만들지 못해 식사를 할 수 없게 된다. 따라서 젓가락에 대한 접근을 하는 것에 대한 문제 해결이 필요한 것이다. 이 문제를 프로그래밍을 통해 해결해보자.



철학자에 대한 정보는 쓰레드와 같다. 젓가락에 대한 접근은 양 옆 철학자에 대해 공통적인 데이터를 접근하는 것과 같다. 임계구역에 접근하는 것과 같아 한 명의 철학자가 젓가락 사용, 즉 임계구역에 접근을 하면 다른 철학자는 그 구역에 접근을 할 수 없다. 그러면 이와 같은 상황을 세마포를 이용해서 상호배타를 만족시키는 상황을 만들 수 있을 것이다. 우선 젓가락과 철학자에 대해 번호를 매긴다. 5개의 임계구역(젓가락)이 만들어져야 하고 각 젓가락 자체가 세마포를 이용해서 접근 제한을 만들기 때문이다. 하나의 젓가락에 대한 세마포는 정수 값의 초기 값으로 1을 가진다. 철학자 한 명이 접근을 하면 다른 철학자가 접근을 하지 못하므로 1명만 접근을 하게 만들기 위해서이다.


철학자라는 쓰레드는 자신의 고유번호를 가지고 왼쪽 젓가락과 오른쪽 젓가락을 가질 수 있다. 먹는 동작과 생각을 하는 동작을 가지고 행동을 하게 된다. 만약 왼쪽 젓가락과 오른쪽 젓가락을 모두 가지게 되면 식사를 하는 동작을 수행하고 그 후 젓가락을 놓고 생각을 하는 동작에 빠지게 된다.


하지만 위와 같은 코드를 실행하면 문제가 발생한다. 바로 모든 철학자가 식사를 하지 못해 굶어 죽는 상황인 starvation인 상태가 발생할 수 있기 때문이다. 우리는 철학자에게 명령을 넣어줄 때 왼쪽 젓가락에 대한 접근을 먼저 주었다. 철학자들은 각자 동작하는 쓰레드이므로 문맥전환이 발생할 수 있다. 그러면 한 명의 철학자가 왼쪽 젓가락에 대한 접근을 하였을 때 문맥전환이 발생했다고 생각해보자. 그 때 자신의 오른쪽에 있던 철학자 쓰레드가 동작하여 왼쪽 젓가락을 잡았다고 생각하자. 그러면 원래 첫 번째로 젓가락을 잡은 철학자 쓰레드의 오른쪽 젓가락을 잡은 것과 같은 상황이다. 이렇게 되면 첫 번째 철학자 쓰레드는 젓가락이 하나 밖에 없어 오른쪽 젓가락을 잡을 수 있는 상황이 될 때까지 기다린다. 왼쪽 젓가락을 잡고 있는 채로 말이다. 그렇게 모든 철학자 쓰레드가 젓가락 하나만 가지고 있는 상태가 되면 프로그램은 돌아가지 않는다. 아무도 식사를 하지 못한 채로 정지되어 있게 된다. 이러한 상황을 starvation이 일어났다고 한다. 1번 쓰레드가 2번 쓰레드의 영향으로 실행을 못하는 상황인데 2번 쓰레드는 1번 쓰레드에 의해 실행을 못하게 되면 두 쓰레드 모두 실행을 하지 못하게 되는 상황이다. 이런 상태를 교착상태라고 한다. 영어로 Deadlock이다. 동기화를 세마포를 통해 설계를 하였는데 교착상태에 빠져 모든 자원이 임계구역에 접근을 하지 못하게 되는 것이다.


Deadlock은 다음 장에서 알아보도록 하자.