시스템 프로그래밍 - semget, semctl
semget
- 세마포어의 생성이나 기존의 생성된 세마포어의 IPC ID를 얻을 때 사용
- 구조
int semget(key_t key, int nsems, int semflg); |
- 설명
1. key_t key = 시스템에서 세마포어를 식별하는 키 번호(IPC_KEY)
2. int nsems = 세마포어 집합 내 세마포어 개수, 접근 제한하려는 세마포어 자원의 수
3. int semflg = 동작 옵션(IPC_CREATE, IPC_EXCL)결정
※ IPC_CREATE : key를 이용하여 새로운 공유메모리 공간 할당
IPC_EXCL : IPC_CREATE와 함께 사용, IPC_CREATE와 함께사용해 만약 공유메모리 공간이 존재하지 않으면 새로 만들어주지만 공유메모리 공간을 사용중이라면 error를 리턴한다.
4. 이미 생성된 세마포어의 세트의 IPC ID만 알아내기 위해서는 sumnum = 0으로 설정해도 된다.
semctl
- 세마포어를 조작하는 함수
- 구조
int semctl(int semid, int semnum, int cmd union semunm arg) |
- 설명
1. int semid = 시스템에서 세마포어를 식별하는 키번호(IPC_KEY)
2. int semnum = 세마포어 집합 내 세마포어의 위치(어느 세마포어를 control 할지 결정)
3. int cmd = 제어명령(값 설정, 삭제, 초기화 등)
※ semctl과 shmctl의 가장 큰 차이 : semctl은 세마포어의 초기화가 가능하다.
4. union semnum arg = 가변변수로써 cmd에 따라 사용여부가 결정 됨
1. semctl에 쓰이는 cmd 값
※ 가변인수 전달 vs 전달 x
1. 가변인수 전달 :
1. SETVAL : semnum위치의 세마포어의 값을 초기화
2. SETALL : semnum위치의 세마포어 배열을 이용해 한꺼번에 초기화
3. GETALL : 세마포어를 배열을 이용하여 한꺼번에 읽어옴
4. IPC_STAT : IPC 자원의 정보를 읽어온다.
5. IPC_SET : IPC 자원의 시스템 정보(권한)를 변경
6. IPC_INFO : IPC 자원의 시스템 설정값을 읽어옴(리눅스 전용)
2. 가변인수 전달 x:
1. GETVAL : semnum 위치의 세마포어의 값을 리턴
2. GETNCNT : semnum위치의 세마포어의 semncnt 정보 리턴
3. GETZCNT : semnum위치의 세마포어의 semzcnt 정보 리턴
4. GETPID : semnu위치의 sempid값 리턴
5. IPC_RMID : IPC 자원 제거
3. cmd 인수값
union semun{
int val; // SETVAL의 인수
struct semid_ds *buf; // IPC_STAT, IPC_SET의 버퍼
unsigned short int *array; // GETALL, SETALL 사용시의 변수 배열
struct seminfo *__buf; // IPC_INFO의 버퍼
4. XSI 세마포어의 함수 생성 및 초기화, 작동
5. 세마포어 ID 데이터 구조체
- IPC_STAT, IPC_SET 명령은 struct semid_ds의 구조체를 이용
- ipcs 명령어에서 세마포어의 정보는 struct semid_ds에서 가져옴
- IPCSET은 EUID가 소유자 or root여야만 한다.
- IPC_SET을 수정하기위해서는 IPC_STAT의 정보 읽기 -> 특정필드 변경 -> IPC_SET으로 갱신
- 세마포어 ID 데이터 구조체
struct semid_ds{
struct ipc_perm sem_perm; // operation permission struct
time_t sem_otime; // semop()를 최근에 한 시간
time_t sem_ctime; // semctl()로 변경한 최근 시간
unsigned long int sem_nsems; // 집합의 세마포어의 개수
};
struct ipc_perm{
key_t __key; // key,리눅스만 사용
uid_t uid; // 소유자 userID
gid_t gid; // 소유자 groupID
uid_t cuid; // 생성자의 userID
gid_t cgid; // 생성자의 groupID
unsigned short int mode; // 읽기 / 쓰기의 권한
unsigned short int __seq; // 생성된 순서대로 붙는 sequence num(리눅스 only)
};
- ipc_perm서 uid, gid, cuid, cgid, mode = sus 표준, __key, __seq = 리눅스 고유 필드