서로 영향을 주고 받는 프로세스, 물리적인 주소 공간을 공유하거나 (스레드) 데이터를 공유하는 프로세스.
하지만 데이터 공유의 동시적인 접근은 데이터 불일치(손실)를 야기할 수 있다.
따라서 우리는 cooperating process를 실행할때 순서대로 실행되도록 보장되어야, 공유된 메모리 등이 동시에 유지될 수 있다.
여러개의 프로세스들이 integrity of data (데이터의 유지, 통일성) 의 공유하고 있을 때
Concurrent execution⇒ 그래서 다음 프로세스가 들어와서 코드를 실행하다보면 문제가 생길 수 있음
⇒ 프로세스는 실행하던도중 어느 포인트 에서든 interrupt 될 수 도 있다
Paralle execution
⇒ 두개 이상의 instruction stream 이 동시에 분리된 코어에 실행 될때 동기화 문제가 생길 수 있다.
동기화 문제
생산자-소비자 문제를 생각해보자
프로세스가 concurrent 하게 동작할때 겉으로 보기에는 P 가 버퍼에 쓸때는 Q가 쉬고, Q가 버퍼를 읽을때는 P가 쉬기 때문에 문제가 없어보인다 ⇒ 하지만 문제가 있다!
예 : 각 프로세스가 concurrent 하게 동작하고, 생산자는 count ++ 하고 소비자는 count -- 하면 제대로 동작할 것 같지만 실제로 context switch가 일어나는 부분이 언제 일어날 지 모르기 때문에 값이 정확하게 출력되지 않는다 ⇒ data integrity가 깨진다
Race Condition
상황 : 두개의 프로세스가 데이터를 공유하고 있는데 concurrent 하게 처리하려고 하려면 어떤 순서에 따라 실행되느냐에 따라 결과가 달라짐
해결 방법⇒ 경쟁 상황을 막는것 : process(or thread) sychronization
run의 내부변수로 선언하여 따로따로 만들면 방지 됨
static 변수로 선언하면 문제가 생김
⇒ IN JAVA
⇒ 특정 시간에 한개의 프로세스만 공유 데이터를 다룰수 있게 한다!
The Critical Section Problem (임계영역)
n개의 프로세스가 있을 때, 어떤 코드 영역을 임계영역이라고 정하자.
그리고 이 임계영역에서 다른 프로세스와 공유된 영역이고, 임계영역에서 업데이트가 일어나게 한다
중요한 것은 한 프로세스가 임계영역에 들어가면, 다른 프로세스는 진입하지 못하게 하자
⇒ 프로세스의 동기화가 확실해진다!
코드의 section
entry-section : 허가를 얻어 임계영역에 들어감
critical-section : 임계영역
exit-section : 임계영역에서 나감
remainder-section : 그 외의 영역
임계영역 문제를 풀 때의 요구사항
Mutual Exclusion(상호배제) : 상호배제를 보장해주어야함
⇒ 한 프로세스가 임계영역을 실행중이라면 다른 프로세스는 진입하지 못해야한다
Progress : (avoid deadlock) : 임계영역으로 가기위해 대기하는 시간이 무한대로 걸리는 것
bounded waiting : (avoid starvation) : 우선순위가 밀려나 계속해서 진입하지 못하는 것
⇒ 제한시간을 주어 기다리는 시간을 정해주는 것
single-core 환경의 해결법
interrupt를 방지한다.⇒ 현재 실행되고 있는 부분을 우선순위 없이 순서대로 실행되게 하는걸 보장해주어야한다
⇒ 멀티프로세스 환경에서는 구현하기 어렵다
⇒ 공유데이터를 수정하는 동안은 interrupt를 사용하지 못하게 한다
두가지 접근
non-preemptive kernel
⇒ 비선점형은 각 프로세스가 자연스럽게 CPU을 놓을 때 까지 나가지 않기 때문에 동기화문제가 일어나지 않는다. 하지만 요즘에는 이러한 방법은 효율적이지 않기 때문에 잘 이용되지 않는다