-
Synchronization대학/시스템소프트웨어 2022. 12. 11. 16:29
두 개 이상의 스레드가 하나의 메모리 공간을 동시에 참조하는 경우,
레이스 컨디션이 발생하여 프로그램을 실행할 때 마다 다른 결과가 출력되는 일이 발생할 수 있다.
이를 방지하기 위해 동기화를 하고, critical section(임계 영역)에 접근할 수 있는 스레드의 수를 제한한다.
동기화를 달성하기 위한 방법으로 mutex와 semaphore가 있다.
- Mutex
mutual exclusion(상호 배제)의 약자로 lock이라고도 한다.
기본적인 아이디어는 임계 영역에 진입할 때는 스레드가 뮤텍스를 잠그고, 나갈 때 잠금을 해제하는 아이디어이다.
즉, 잠겨있는 뮤텍스 아래로는 실행이 불가능하다.
뮤텍스를 사용할 때 주의할 점은, 임계영역으로 진입한 스레드가 뮤텍스를 풀기 전 중지되면 안된다는 것이다.
뮤텍스를 잠그고 중지될 경우 프로그램이 데드락 상태에 빠질 수 있기 때문이다.
또한, 뮤텍스는 전역변수로 선언하여 모든 스레드에서 접근 가능한 상태로 만들어야 한다.
// 뮤텍스 생성 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //or pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); // 뮤텍스로 임계영역 설정 pthread_mutex_lock(&mutex); // critical section pthread_mutex_unlock(&mutex);
임계 영역과 스레드간 time-slice 관점에서 어떻게 동작하는지 살펴보자.
- Semaphore
세마포어 역시 뮤텍스와 동일한 방식으로 사용한다.
하지만, 중요한 차이점은 뮤텍스는 임계 영역에 단 하나의 스레드만 접근 가능하다면,
세마포어는 이 숫자를 조정할 수 있다.
임계 영역에 접근 가능한 스레드의 수를 1로 설정한 세마포어를 Binary Semaphore라 하고,
2개 이상으로 설정한 세마포어를 Counting Semaphore라고 한다.
// system V semaphore pid_t semid = CreateSemaphore("abc", 1); // binary semaphore wait(&semid); // critical section signal(&semid);
마찬가지로 임계 영역과 스레드간 time-slice 관점에서 어떻게 동작하는지 살펴보자.
위의 경우는 system V 패키지에서 제공하는 익명 세마포어의 코드였다.
이번에는 POSIX 라이브러리에서 제공하는 Named Semaphore를 살펴보자.
#define PERMS (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) //0644 #define FLAGS (O_CREAT) int main(void) { sem_t *semid; if ((*sem = sem_open("my_sem", FLAGS, PERMS, 1)) == SEM_FAILED) // binary semaphore return -1; sem_wait(sem); // critical section sem_post(sem); if (sem_close(sem)) return -1; sem_unlink((const char*)"my_sem"); // 세마포어 완전 삭제 return 0; }
'대학 > 시스템소프트웨어' 카테고리의 다른 글
Linking (0) 2022.12.11 Memory Management (0) 2022.12.11 Threads (0) 2022.12.11 Inter-Process Communication (2) 2022.10.23 Timer (0) 2022.10.22