동기화 synchronous
프로세스들이 동작은 맞추는 것
작업을 요청 후 결과 값이 나올 때까지 기다리는 것을 의미합니다. ( blocking )
비동기화 asynchronous
프로세스들이 서로에 대해 모름
작업을 요청 후 결과값이 나올 때까지 기다리지 않고 다음 코드를 실행하는 것을 의미합니다. (non-blocking)
결과 값은 이벤트큐에 넣거나 백그라운드 쓰레드에 위임합니다.
언제 필요할까?
여러 프로세스(쓰레드)가 공유 자원을 동시에 사용할 때 문제가 발생할 수 있습니다.
이러한 상황을 race condition이라고 부르는데, 둘 이상의 프로세스( 또는 쓰레드)가 하나의 데이터에 접근할 때 동기화 되지 않은 상태
따라서, 프로세스를 공유 자원의 접근을 제한하여 문제가 생기지 않게 방지하는 것이 목표입니다.
용어
Shared data ( or critical data )
여러 프로세스들이 공유하는 데이터, 자원
공유할 때 잘못건들면 위험하기 때문에 critical data라고도 불립니다.
Critical Section ( 임계 영역 )
각 프로세스에서 critical data에 접근하는 코드 영역 ( code segment )
CS라고도 표현합니다.
Mutual exclusion ( 상호 배제 )
둘 이상의 프로세스가 critical section에 동시에 진입하는 것을 막는 것
동기화 방법의 종류
뮤텍스, 상호 배제 ( mutual exclusion )
- 프로세스의 동시 접근을 허용하지 않는다는 의미.
- cs 접근을 조율하기 위해 뮤텍스 lock을 이용합니다. lock이 있는 프로세스만 임계 영역에 들어갈 수 있습니다.
- 뮤텍스는 상태가 0, 1로 binary semaphore라고도 불립니다.
- 커널에서 제공
스핀락 ( spin lock )
- 뮤텍스처럼 lock을 이용한 상호배제를 합니다.
- 하지만, lock을 갖지 않는 다른 프로세스들은 loop를계속 돌며(spin) 기다린다는 차이가 있습니다.
- 따라서, 뮤텍스는 lock을 얻을때, context switch라는 상대적으로 무거운 작업을 해야하지만, 스핀락은 context switch 없이 기다립니다. 연산이 간단한 경우에는 스핀락이 더 효율적이지만, 스핀이 길어진다면 cpu에 더 부담을 주는 단점이 있습니다.
세마포어 ( semaphore )
- 세마포어 역시 뮤텍스와 비슷한 역할을 하지만, 세마포어는 동시 접근 동기화가 아닌 접근 순서 동기화에 더 관련있습니다.
- 지정된 갯수 만큼만 쓰레드가 동시에 실행되도록 합니다.
즉, 세마포어는 여 러개의 쓰레드가 동시에 cs에 들어가게 할 수 있습니다. ( counting semaphore )
- 뮤텍스와 비슷하게 작동하지만, 가장 큰 차이점은 동기화 대상의 갯수입니다.
- 세마포어 값이 0이라면 프로세스는 기다리게 됩니다. 그런데, spin lock으로 기다릴 수 있지만, cpu 낭비가 생깁니다.
따라서, 세마포어가 0이라면 wait() 시스템 콜을 이용해 세마포어 큐에 blocked 상태로 대기하게 됩니다.
(그리고 cpu 스케줄러에 의해 다른 프로세스가 실행됩니다.)
세마포어 값이 다시 증가하면 signal() 시스템 콜로 세마포어 큐에 있는 프로세스를 다시 실행시키게 됩니다.
- 커널에서 제공
- 세마포어는 뮤텍스가 될 수 있지만, 뮤텍스는 세마포어가 될 수 없습니다. (세마포어가 허용가능한 쓰레드를 1개로 지정할 경우)
- 하지만, 데드락이 발생할 수 있습니다
세마포어에서 허용된 둘 이상의 프로세스가 서로 Critical Section 진입을 기다리고 있고, Critical Section 에서 실행되는 프로세스는 진입 대기 중인 프로세스가 실행되야만 빠져나올 수 있는 상황을 지칭합니다.
모니터
- 하나의 프로세스에서 쓰레드 간 동기화를 위해 사용됩니다.
- mutex와 conditional variable을 이용한 동기화 방법
- 쓰레드간에 뮤텍스로 동기화를 합니다.
하지만, 데드락이 발생할 수 있는 경우가 있습니다. 이 때, 데드락을 방지하고자, 데드락 발생 가능한 쓰레드를 어떤 condition이 false인 동안 lock을 잡지 않고 기다리는 방법입니다.
- 이해하는데 도움받았던 블로그 : https://nosyu.pe.kr/2243
- 주로 고급 언어에서 지원됩니다. Java에서 기본적으로 모든 객체에 monitor가 제공됩니다.
뮤텍스 vs 모니터
가장 큰 차이는 (커널제공) 뮤텍스는 다른 프로세스(애플리케이션)간에 동기화를 위해 사용한다.
반면 모니터는 하나의 프로세스(애플리케이션)내에 다른 쓰레드 간에 동기화할 때 사용한다.
또한, 뮤텍스는 보통 운영체제 커널 의해서 제공되는 반면에
모니터는 프레임워크나 라이브러리 그 자체에서 제공된다.
따라서 뮤텍스는 무겁고(heavy-weight) 느리며(slower)
모니터는 가볍고(light-weight) 빠르다(faster)
세마포어 vs 모니터
세마포어는 프로그래머가 직접 키 해제와 공유자원 접근 처리가 필요하다. 세마포어는 접근 갯수만 관리하기 때문
모니터는 공유자원에 접근하기 위한 키 획득과 자원 사용 후 해제를 모두 처리한다.
캡슐화되어 있어 synchronized, wait(), notify() 등의 키워드를 이용해 좀 더 편하게 동기화할 수 있다.
세마포어 vs 뮤텍스
세마포어는 뮤텍스가 될 수 있지만
뮤텍스는 세마포어가 될 수 없다.
세마포어는 소유할 수 없는 반면,
뮤텍스는 소유할 수 있고 소유자가 이에 책임을 진다.
( 따라서, 세마포어의 경우 다른 프로세스가 락 해제가 가능하지만 뮤텍스는 불가능하다 )
뮤텍스는 1개만 동기화가 되지만
세마포어는 하나 이상을 동기화 할 수 있다.
참고 블로그
'CS > OS' 카테고리의 다른 글
OS 부팅과정 (2) | 2023.11.21 |
---|---|
address space VS virtual memory VS swap memory (0) | 2020.07.13 |
데드락 (DeadLock) (0) | 2020.06.23 |
process vs thread (0) | 2020.04.27 |
IPC(Inter Process Connection) (0) | 2020.04.25 |