synchronization. 작업 사이의 수행 시기를 맞추는 것
프로세스 동기화 : 프로세스들 사이의 수행 시기를 맞추는 것
❗ 스레드도 동기화 대상. 실행의 흐름을 갖는 모든 것은 동기화의 대상임
#include <iostream>
#include <queue>
#include <thread>
using namespace std;
void produce();
void consume();
//queue<int> q;
int sum = 0;
int main() {
cout << "초기 합계: " << sum << endl;
thread producer(produce);
thread consumer(consume);
producer.join();
consumer.join();
cout << "producer, consumer 스레드 실행 이후 합계: " << sum << endl;
return 0;
}
void produce() { // 버퍼에 데이터 삽입
for(int i = 0; i < 100000; i++) {
// q.push(1);
sum++;
}
}
// 주석된 코드들을 해제하고 실행하면 레이스 컨디션이 발생하여 오류. 해제 하지 않아도 오류
void consume() { // 버퍼에 데이터 빼내기
for(int i = 0; i < 100000; i++) {
// q.pop();
sum--;
}
}
실행 결과 
💡 레이스Race 컨디션
잘못된 실행으로 인해 두 개 이상의 프로세스나 스레드가 동일한 자원을 동시에 접근하여 수정하려 할 때, 접근 순서에 따라 결과가 달라지는 상황

Mutex lock; MUTual EXclusion Lock
동시에 접근해서는 안되는 자원에 않도록 만드는(상호배제) 도구. 임계구역에 자물쇠를 걺. 하나의 공유 자원에 접근하는 경우 상정
- 자물쇠 : 프로세스들이 공유하는 전역 변수 lock
- 임계구역 잠금 : acquire 함수
임계구역이 잠겨있다면 lock이 false가 될 때까지 임계구역 반복적 확인
열려있다면 lock을 true로 바꿈- 임계구역 잠금 해제 : release 함수
임계구역에서 작업이 끝나고 호출하는 함수. 현재 lock을 false로 바꾸는 함수acquire() { while (lock == true) //임계구역이 잠겨있는동안 ; //임계구역 잠겨있는지 반복적 확인. busy wait lock = true; //임계구역 안잠겨있으면 잠금 } release() { lock = false; //임계구역 작업이 끝나면 잠금 해제 }💡 바쁜 대기busy wait : 반복적으로 계속해서 잠김 확인
semaphore. 공유자원이 여러개 있는 상황에서 적용이 가능한 동기화 도구
- 전역 함수 S : 임계구역에 진입할 수 있는 프로세스 개수(사용가능한 공유자원의 개수)
- wait 함수(down, P) : 임계구역에 들어가도 좋은지 / 기다려야 할지 알려줌
- signal 함수(up, V) : 임계구역 앞에서 '들어가도 좋다' 신호를 줌
wait() { S--; //임계구역에 진입할 수 있는 프로세스가 하나 이상이면 S를 1 감소, 임계구역 진입 if (S < 0) { //사용가능한 자원이 없는 경우 Add this process to Queue; //해당 프로세스 PCB를 대기 큐에 추가 sleep(); //대기상태로 전환 } signal() { //프로세스가 임계구역 작업끝나고 호출 S++;//임계구역 작업 마친 후 S를 1 증가 if (S <= 0) { remove a process p from Queue; //대기 큐에서 프로세스 PCB를 제거 wakeup(p); //프로세스 p를 준비상태로 전환 } }⇒ 세마포는 busy wait이 없음!!!
💡 세마포의 종류
- 이진 세마포binary semaphore : S가 0과 1 두 종류의 값만 가짐
- 카운팅 세마포counting semaphore : S가 0이상의 값 가짐
세마포의 변수를 S = 0으로 두고, 먼저 실행할 프로세스 뒤 signal(), 다음에 실행할 프로세스 앞 wait()
monitor. 공유자원과 공유자원에 접근가능한 인터페이스(통로)를 묶어서 관리.
자원에 접근하고자 하는 프로세스를 큐에 삽입하고, 큐에 삽입된 순서대로 하나씩 공유자원을 이용하도록 함.
❗ 모니터 안에는 하나의 프로세스만 존재 가능. 자원 하나당 모니터 하나
💡 여기서 인터페이스는 공유자원을 제어하기 위한 메소드
(이미지에서 3개 인것일뿐 더 있을 수 있다)
실행 순서 제어를 위한 동기화 제공
→ 조건 변수condition variable : 특정 조건 바탕으로 프로세스 실행/일시중단 하는 변수(모니터와는 별개의 개념임)
모니터로 진입한 프로세스가 x.wait() 로 변수 x에 대한 wait를 호출했다면 x.signal() 을 통해 대기상태 → 준비상태가 되어 다시 모니터 안으로 들어올 수 있다.