상호배제
사진을 보면 입력프로세스와 출력프로세스가 같은 장소에서 작업을 처리하는 것을 알 수 있다.
즉 공유자원을 사용중인데, 이런 경우 관리가 필요하다,
또한 아래를 보면 프로세스2가 a를 사용중이고 a구하는 프로세스도 존재한다,
이런 경우 a는 공유 자원이다.
공유자원에 관리가 없이 무단 사용이 된다면 오류가 발생할 수 있다.
따라서 이를 관리할 방법이 필요한데 이를 담당하는 코드를 임계영역(Critical section)이라고 한다.
위 사진을 보면 A가 임계영역에 먼저 진입한 것을 알 수있다.
T2에서 B도 임계영역에 접근하였지만 막힌것을 볼 수 있다.
즉 임게영역에 누군가 먼저 접근하였다면 다른 프로세스를 막는 것을
"상호 배제"라고 한다.
임계영역을 만약 A,B가 공유하여 동시에 사용하면 오동작의 위험이 커진다.
따라서 이를 상호 배제 하여 위험을 줄인다.
하지만 무분별한 상호배제는 성능 하락을 가져올 수 있기 때문에 조심해야한다.
위 사진은 임계영역에 대해서 다루고 있다.
위 사진에는 총 3가지 영역이 등장한다.
1. 진입영역 : 프로세스가 임계영역에 진입하기 전에 상호 배레즐 보장하기 위한 코드로,
다른 프로세스가 이미 임계영역에 있다면 진입을 대기해야한다.
2. 임계영역 : 여러 프로세스가 동시에 접근하면 안되는 코드의 일부이다, 예를 들어 두 프로세스가
동시에 임계영역에서 변수를 수정하려고 하면 데이터 충돌이 발생할 수 있다.
3. 출구영역 : 프로세스가 임계영역을 벗어난 후 실행되는 부분이다, 다른 프로세스가
임계 영역에 들어갈 수 있도록 상호 배제를 해제하는 작업을 처리한다.
병행처리과정에서의 생산자, 소비자
위 사진은 유한버퍼를 이용한 병행프로세스 처리를 나타낸 이미지이다.
가운데를 보면 0번째 비트에 in, out이 존재한다,
만약 생산자가 하나를 추가하면 in은 다음 칸으로 이동, 0번째에는 들어온 항목이 추가된다.
만약 항목이 하나 빠져나가면 out은 다음 칸을 가리키고 0번째는 빈칸이 된다.
다음의 조건을 유의해야한다.
1. In==out -> Empty
2. ((in + 1) % n) == out -> Full case
3. in > out -> Other case
예시
위에 방법은 최종적으로는 한칸을 못쓰게 되는 비효율이 발생한다,
따라서 이 문제를 해결하기 위해 다음에 방법을 사용한다.
이 방법에는 counter라는 값을 이용해 가득 찼는지 확인하는 방식이다.
시작 시 counter 값ㅇ르 0으로 고정하고,
값을 추가할 때마다 값을 확인 후 홀딩한다.
이를 통해 버퍼를 풀로 사용이 가능해진다.
하지만 이 방식도 여전히 문제가 존재한다.
위 예시를 살펴보자
우선 counter값은 5로 시작된다,
생산자 프로세스는 값에 1을 추가하면 6이된다,
소비자 프로세스는 값에 1을 감소시켜 4가 된다.
하지만 이 경우 6이 된후 4로 오버라이트 되는 문제가 발생한다.
즉 임계영역이 발생하는 것이다. -> race condition이라고 부르는 문제 발생