현대 컴퓨터의 메모리에는 여러 프로세스가 존재하는데, 이러한 프로세스들이 하나의 공유 메모리나 또 다른 프로세스에 접근할 때는 매우 신중해야 한다. 이처럼 한 프로세스가 다른 프로세스에게 영향을 받거나 주는 프로세스를 Cooperating process라고 한다. 반대로 아무런 영향을 미치지 않는 독립적인 프로세스는 Independent process이다.
현대 컴퓨터 환경에는 cooperating process가 훨씬 많이 존재하고, 이들은 서로 영향을 미치기 때문에 데이터나 흐름에 대한 동기화가 매우 중요하다. 프로세스 사이에 동기화를 하는 것을 프로세스 동기화(Process Synchronization) 라고 한다.(현재에는 대부분 쓰레드 기준으로 스위칭을 하므로, Thread synchronization으로 많이 불린다.)
대표적인 예로 기차표 예매가 있다. 어느 시간에 한 좌석의 기차표는 반드시 하나만 존재해야한다. 그런데 이를 예매하려는 사용자(프로세스)는 여러 명이다. 이 사용자들이 동시에 하나의 좌석 기차표를 구매하려고 하면 어떠한 일이 발생할까? 실제 환경에서는 당연하게도 동기화 문제를 해결한 시스템이므로 한 사람만이 기차표를 예매할 수 있을 것이다. 만약 동기화에 문제가 발생한다면 한 기차표를 여러 사람이 예매하는 불상사가 발생할 수 있다.
프로세스 동기화는 여러 프로세스가 공유하는 자원의 일관성을 유지하는 것이다. 가령 여러 프로세스가 동시에 하나의 공유된 자원에 접근하려고 할 때 이 프로세스들의 순서를 정하여 데이터의 일관성을 유지시켜주어야 한다.
여러 개의 프로세스들이 공유 자원에 동시적(concurrent)으로 접근할 때, 접근 타이밍과 순서에 따라 그 결과가 달라져서 데이터 일관성(Data Consistency)을 해칠 수 있는 상태를 뜻한다.
은행에서 사용자 A와 사용자 B가 입급과 출금을 한다.
처음 계좌에 있던 돈은 2000원이다.
사용자 B 은행 시스템이 더 빨라서 사용자 B가 1000원을 뽑고 나서 사용자 A는 500원을 입금하면 원래 계좌에 있는 돈은 1500원이지만, 계좌에는 2500원이 있는 문제가 생긴다.
이처럼 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황을 '경쟁 상태가 발생했다고' 한다. 경쟁 상황이 발생하면 이와 같이 공유 자원 접근 순서에 따라 실행 결과가 달라질 수 있다.
따라서 이런 경우에는 프로세스 동기화를 해야 한다. 프로세스 동기화는 대표적으로 임계구역 문제 해결과 프로세스 실행 순서 제어에 초점을 두고 있다.
void deposit(int amount) {
balance = balance + amount;
}
void withdraw(int amount) {
balance = balance - amount;
}
위 코드는 은행계좌 문제에서의 임계구역이다.
임계구역을 해결하기 위해서는 3가지 조건이 만족해야한다.
상호 배제(Mutual exclusion): 임계구격 내에는 한번에 하나의 쓰레드만이 진입 가능하다. 한 쓰레드가 이미 임계구역에서 수행 중인 상태에서는 다른 쓰레드는 절대 이 구역에 접근할 수 없다.
한정 대기(Bounded waiting): 임계구역으로 진입하기 위해 대기하는 모든 쓰레드는 유한 시간 이내에 해당 임계구역으로 진입할 수 있어야 한다. 만약에 하나의 프로세스가 들어가서 오랫동안 나오지 않으면 기아
로 인해 다른 프로세스는 실행시킬 수 없게 됩니다.
진행의 융통성(Progress flexiblity): 한 프로세스가 다른 프로세스의 진행을 방해해서는 안된다.