Synchronization
📢 동기화
타임도 메인에서 똑같이 시작해서 똑같이 끝나도록
📌 동기화가 필요한 상황
- 두 개이상의 프로세스 , 스레드가 동작하는 가운데 shared data를 동시에 사용하려는 상황에
To share resources, access shared data structures
- 시간적인 동기화가 필요한 경우,
to coordinate their execution
✔ IPC
→ message aueue
: 운영체제가 다 알아서 해줌 운체가 개입하는 시간이 많아져서 오버헤드가 큼
→ shared memory
: 메모리를 할당해준 후 운영체제j가 개입을 하지 않음. 할거 다 했을 때 메모리 공간 free해줄 때, 시작과 끝만 개입을 한다. 일반적으로.
- 두 개 이상의 프로세스가 스레드가 여러개 있을 때 공유하는 자원이 있다면 그 자원에 저장되어 있는 데이터가 왜곡될 수 있다 → context switching 때문에
- 공유자원을 다수의 프로세스나 스레드를 동시에 접근할 때 발생할 수 있는 문제
- 개발자들이 문제를 핸들링해야한다.
동기화 문제(Synchronization Problem, Critical Section Problem)
race condition
: concurrrent 하게 동작하는 두개 이상의 스레드와 프로세스가 동일한 shared resource에 접근하려고 하는 상황
- race condition에 별다른 장치를 하지 않으면
non-deterministic
하게 동작을 한다. context switching되는 타이밍에 따라 원래 의도대로 동작할 수도 이상한 값이 나올수도 있다.
⇒ 이런 문제를 동기화 문제(Synchronization Problem)라고 한다.
- 동기화 문제가 발생할 수 있는 코드 section을
Critical section
이라고 한다.
동기화 문제 해결을 위해 갖추어야할 조건
1. Mutual Exclusion (상호 배재)
문제가 발생할 수 있는 critical section에 다수의 프로세스가 진입을 할 때, 이 코드 섹션은 한 번의 하나의 프로세스만 접근해야한다.
: 쉐어드 리소스에 동시에 접근할 수 있는 것은 무조건 하나여야 한다.
2. Progress
- 공유자원 없을 때 기다리지 않아야 한다.
- 아무도 안 쓰고 있는데 기다릴 필요가 없다
- 크리티컬 섹션에 들어가야하는데 아무도 안 쓰고 있으면 기다리지 않고 그냥 진입해야한다.
3. Bounded Waiting
- 기다리는 시간이 무한하지 않아야 한다.
- 계속해서 무한정 기다리면 안된다.
- critical section에 누가 사용하고 있으면 기다려야 하는데 무한정 기다리는것이 아니라 언젠가는 내 차례가 와야한다.
🔒 Lock
- lock(): wait until lock is free, then grab it
→ 공유 자원을 아무도 안 쓰고 있으면 lock을 걸고 사용 가능
→ 만약 누가 공유 자원을 사용 중이라서 lock이 걸려 있다면 공유 자원을 사용하고 싶은 해당 프로세스는 기다린다.
- unlock(): unlock, and wake up any thread waiting in lock()
✅ Problem
- lock 자체가 ctitical section
→ 한 프로세스가 lock을 걸고 while loop를 돌다가 다음으로 넘어가는 시점에 held 값을 바꾸기 이전에 다른 프로세스가 lock을 호출한다면 두 프로세스다 critical section으로 접근할 수 있다. ⇒ mutual Exclusion 만족 x
✅ Solutions
- Software-only algorithms
→ 성능이 안 좋다, 실제 운영체제에서는 사용되지 않는다.
- Hardware atomic instructions
→ lock을 걸고 푸는 것을 하나의 instruction으로 만든다면 중간에 interrupt가 걸리지 않고 mutual Exclusion 하게 만들 수 있을 것임. → 가능하려면 cpu 제조사가 지원을 해주어야 한다. cpu dependency높아야한다.
① Test-and-Set
- Disable/re-enable interrupts
- lock 수행하기 전에 interrupt를 enable 시키면 된다
- no busy waiting
Problems with Spinlocks
운영체제에서만 쓴다. 사용자가 사용할 수 있는 버전의 싱크로 툴을 만들기 위해서 사용
Semaphore
정수 값으로 카운트설정 가능, 카운트가 티켓 critical section에 들어갈때 wait이라는 시스템 콜 → 변수가 하나 죽어 티켓을 하나 가져감
✔ Semaphore Usage
critical section을 보호하는거 자체가
- 버그가 많다는 것은 글쎄 문제가 없는뎅? 교수님은 동의를 못 하겠다
- 사용하기 어렵긴 하다
💭소프트웨어 버그도 많이 생기고 더 쉽게 할 수 없을까?
→ 하다가 나온게 Monitor : 컴파일러 레벨에서 지정만 해주면 크리티컬 시그널을 런타임에 거기서 발생하는 예외사항도 처리해주는 자동으로 다 해주게 하자!!!
Monitors
: Java에서 사용, 한 프로세스에서 monitor에서 있는 함수를 사용하고 있으면 다른 프로세스에서 사용이 불가
-
만약 한 프로세스가 monitor에 있는 함수를 수행하던 중 이벤트가 발생해 기다려야 하는 상황이 발생하면 기다리는 동안 다른 함수들이나 프로세스가 실행이 불가하다
-
conditional variable
- wait : 이벤트를 기다릴 때
- signal : 이벤트가 끝났을 때
-
Monitor와 Semaphores에 차이점 : Semaphore에는 history가 남는다.