동기화(Synchronization)가 필요한 이유
두 개의 프로세스가 동일한 공유된 메모리에 접근.
- 프로세스는 서로 협동하여 규칙을 준수하며 사용 해야 한다.
- 잘못된 연산을 없애고 일관성을 보장해야 한다.
응용프로그램에서 동기화 방식
- Semaphore
- MUTEX
- Condition Variable<
이러한 기법을 통해서 잠금을 하여 한번에 한 스레드만 접근하도록 제한을 한다.
세마포어 란?
- - 실행 중인 여러 태스크가 동기화 또는 상호 배제를 목적으로 획득하거나 반환할 수 있는 커널 오브젝트
세마포어의 필요성
- - 여러 태스크가 동시에 동작하는 응용 프로그램에서 태스크 간의 동작을 동기화해야 한다.
- - 공유 자원에 접근하고자 하는 태스크가 독점적으로 자원에 접근할 수 있도록 관리할 수 있는 방법이 필요하다.
세마포어의 유형
- 이진 세마포어 binary semaphores ( 0,1 을 사용합니다.)
- 계수 세마포어 counting semaphores (예시- 원하는 만큼 공유 자원을 할당 할수 있다. 즉 5개를 주면 5,4,3,2,1에서 0이 되는 순간 자원을 다쓴 형태입니다. )
세마포어에 대한 연산 (값을 초기화 하거나 내리거나 올리거나 할수 있는 연산)
- nitialize (create)
- wait (pend)
- post (signal)
리눅스에서 세마포어의 형식
- 이름 없는 세마포어 (Unnamed Semaphore)
- 세마포어가 프로세스 메모리 내에 존재하기 때문에 스레드간에 사용하는 경우 전역변수를 사용
- 프로세스간에 사용하는 경우는 공유메모리에ㅐ 세마포어를 만들어 줘야 함
- 이름 있는 세마포어(Named Semaphore)
- 세마포어가 파일 형태로 만들어지기 때문에 파일 이름만 알면 세마포어를 사용할 수 있음
- 파일 이름은 최대 251문자 까지 가능
- Kernal 버전 2.6.19부터는 /dev/shm/ 위치에 sem.[이름] 형태로 파일이 생성됨
세마포어의 동작 !
동작
- 태스크가 세마포어를 획득할 경우, 태스크는 원하는 동작을 수행하거나 공유 자원에 접근할 수 있다.
- 태스크는 하나의 세마포어를 여러 번 획득할 수 있다.
- 이 횟수에는 제한이 있으며, 이 값은 세마포어를 생성할 때 결정된다.
- 커널은 세마포어의 토큰 카운트 값을 통해서, 세마포어의 획득 횟수를 알 수 있다.
- 세마포어 카운트가 한계 값에 도달하면, 이미 세마포어를 획득한 다른 태스크가 바노할할 때까지 다른 태스크는 더 이상 세마포어를 획득할 수 없다. (즉 값이 0이 되었을경우)
- 토큰 카운트가 0이 되었다면, 세마포어를 요청한 태스크는 세마포어를 획득할 수 없으므로, 세마포어가 사용 가능해질 때까지 블록 상태로 대기하거나 세마포어 획득을 포기한다.
- 세마포어 대기 리스트로 대기중인 태스크들을 관리한다.
세마포어 변수를 사용하는 스레드 :
세마포어의 동작을 위한 변수 필요 :
sem Count = 1;
thread_with_critical_section() {
// critical_section 이란 단 한번만 접근해서 처리해야한다. 여러개가 접근하면 망가질수 있는 코드 사이에 세마포어를 넣어줘야합니다.
sem_wait(&sem);
Critical_section
sem_post(&sem);
}
인 상태에서 첫번째 스레드(T1)일 실행되는 동안 스레드2(T2)가 접근하면 sem sleep queue을 줘서 잠시 대기 상태로 만들어 놓습니다.
sem_post인 상태에서 값이 0에서 1이 되어버리면 sem sleep에 있던 값들을 (한번에) ready queue에 넣고 우선 순위 높은것을 고른 후에 진행을 하게 됩니다.
예시)
sem Count =3이면 t1,t2,t3가 한번에 들어가서 실행을 할수 있습니다.
세마포어 변수를 사용 하는 스레드
- 접근한 순서는 T1 -> T2 -> T3 순이다.
- 우선순위는 T3 ->T2 ->T1 순이다.
- 초기화 된 세마포어 변수 sem을 T1, T2, T3 각 3개의 스레드가 잠그려 하는 상황이다.
- 세마포어를 잠글 때에는 sem_wait() 함수를, 풀어줄 때에는 sem_post() 함수를 사용한다.
- T1이 sem을 잠그면서 sem의 count를 하나 감소시킨다. count가 0이 되면 이후 이 세마포어를 잠그려는 스레드는 block되게 한다.
- T1의 상호 배제 구역 수행 중에 sem을 잠그려 한 T2와 T3는 sem의 sleep queue에 들어가 block 된다.
- T1이 sem을 풀면서 sem의 count를 하나 증가시키고 sleep queue에 block 되어 있던 T2 와 T3를 read queue로 넣어준 후 return 한다.
상호배제 문제
- 세마포어는 아무 스레드나 post가 가능하기 때문에 critical section을 보호하기 위해 사용하는 경우 잘못 사용하면 상호배제(mutual exclusion)를 보장할 수 없을 수도 있으므로 주의해야한다.
post가 가능하기 때문에 잘못사용을 하면 상호 배제를 보장하지 못하고 sem_post를 여러 번 한것같이 될수 있습니다.
즉 소유의 개념이 없습니다.
실행 순서 동기화
- 실행 순서 동기화를 목적으로 세마포어를 사용하면 초기값을 0으로 해야합니다.
a 와 b 중에 b를 실행할때 뒤에 실행 시켰다고 하더라도 값이 0이라면 block처리가 되고 a가 값을 처리하고 b를 처리하게 됩니다.
0으로 세탕하고 순서를 맞춰줄수 있습니다.
'lecture' 카테고리의 다른 글
기술 면접 질문 모음 (0) | 2023.09.14 |
---|---|
멀티프로세싱과 멀티스레딩, 그리고 IPC (0) | 2023.06.01 |
알고리즘 퀵 정렬(quicksort) 이란 ? (0) | 2023.01.30 |
재귀용법 (recursive call, 재귀호출) (0) | 2023.01.17 |
정렬 알고리즘 - 1 (0) | 2023.01.15 |