티스토리 뷰
Semaphore 도 IPC로 분류가 되는데, 앞서 알아봤던 Message Queue, Shared Memory와 같이 서로다른 프로세스간 데이터 전송을 목적으로 둔 것이 아니다.
Semaphore 은 프로세스간 데이터를 동기화하고 보호하는데 목적을 둔다.
그런데 왜 IPC로 분류를 할까 ?
Semaphore 도 결국 서로다른 프로세스간 통신을 함에 있어서 동기화 문제를 해결하기 위해 사용되기 때문이다. 결국 프로세스간 통신을 함에 있어서 사용되는지 여부가 중요한 것이다. (?)
Semaphore 의 과정
- 세마포어 생성
- 임계구역 잠금
- 공유자원 사용
- 임계구역 잠금해제
- 세마포어 제거
위 5가지 과정을 통해 Semaphore을 이용해 서로다른 프로세스간의 통신에서 동기화 문제를 해결한다.
이 때 Linux에서 Semaphore는 POSIX 기반, System V 기반으로 나뉘어진다.
[ System V Semaphore ]
int semget(key_t key, int nsems, int semflag);
- key : key는 semaphore을 식별할 수 있는 식별자.
nsems : semaphore의 개수. ( 열쇠의 개수라 생각하면된다. )
semflag : O_CREAT, O_EXCL, 0666 등의 semaphore의 플래그.
int semop(int semid, struct sembuf* buf, unsigned int nsops);
- semid : semget을 통해 생성된 semaphore을 구별하기 위한 반환값.
buf : 해당 semaphore에 특정 연산을 하기 위해 주어지는 구조체.
struct sembuf* sembuf = { 0, 1, SEM_UNDO }; // 각각 Index, 증감값, flag 이다.
struct sembuf* sembuf2 = { 0, -1, SEM_UNDO };
와 같이 정의해둔 뒤 인자로 준다.
nsops : 변경하고자하는 세마포어의 개수.
int semctl(int semid, int semnum, int cmd, union semun buf);
- semnum : Semaphore의 인덱스이다. ( semget에서 한 개만 했을 시 0 )
cmd : IPC_STAT, IPC_SET, IPC_RMID, SETVAL, ... ( 등등 많더라.. )
buf : IPC_STAT 했을 시 읽어온 Semaphore의 정보를 저장할 구조체 변수.
- union semun semunBuf;
semunBuf.val = [ 0 | 1 ];
semctl(semid, index, SETVAL, semunBuf); 와 같이 세마포어의 값을 변경할 수도 있다.
[ POSIX Semaphore ]
- POSIX Semaphore은 또 2가지로 분류된다.
하나는 이름을 가지는 named semaphore, 다른 하나는 익명으로 수행되는 unnamed semaphore이다.
[ POSIX Named Semaphore ]
sem_t* sem_open(const char* name, int oflag, mode_t mode, int value);
- name : Semaphore를 구분하기위한 이름.
oflag : O_CREAT, O_EXCL 와 같은 flag.
mode : Semaphore에 부여하는 권한.
value : Semaphore에 부여하는 초기값.
int sem_wait(sem_t* semid);
- Semaphore의 count를 1감소 시키고, 0일경우 Block해 접근하지 못하도록 한다.
int sem_post(sem_t* semid);
- Semaphore의 count를 1증가 시킨다.
int sem_unlink(const char* name); - 해당 이름의 Semaphore을 해당 프로세스에서 분리.
int sem_close(sem_t* semid); - 한쪽 프로세스에서만 수행하면된다.
( 반드시 unlink를 하고 close를 해야된다. )
[ POSIX unNamed Semaphore ]
- unnamed semaphore은 당연히 하나의 파일에서만 가능하다.
다른 프로세스와 통신을 허용하다고 하더라도 fork를 이용한 경우에만 가능하다.
int sem_init(sem_t* sem, int pshared, unsigned int value);
- sem : Semaphore 변수의 주소값. ( sem_t sem → &sem )
pshared : 다른 프로세스와 공유하는가에 대한 옵션.
value : Semaphore 의 초기 값.
이후에는 sem_wait, sem_post를 동일하게 사용하면 된다.
int sem_destroy(sem_t* sem);
* System V Semaphore와 POSIX Semaphore의 차이점.
- System V가 POSIX에 비해 조금 더 고전적이고 어려운 편이다.
- System V가 POSIX에 비해 성능이 조금 안좋다.
- System V와 다르게 POSIX는 named와 unnamed가 나뉘어져 있다.
* Semaphore와 Mutex의 차이점.
- 간단하게 말하면 mutex는 하나의 프로세스에서 여러 개의 스레드간의 동기화처리를 위해 존재하고,
semaphore는 서로 다른 여러 개의 프로세스간의 동기화 처리를 위해 존재한다.
- 추가적인 차이점은 아래 내용을 참고하자.
'운영체제(OS)' 카테고리의 다른 글
[OS] 페이지 교체(Page Replacement) (0) | 2019.12.16 |
---|---|
[OS] Memory ( 가상메모리 ) (0) | 2019.12.16 |
[OS] "동적연결 & 공유" 라이브러리 (1) | 2019.11.20 |
[OS] 실시간 CPU 스케줄링 (0) | 2019.11.04 |
[OS] 다중 처리기 스케줄링 (0) | 2019.11.04 |