(본 강의 노트는 한빛 아카데미의 <유닉스 시스템 프로그래밍> 책을 기반으로 하고 있습니다)
학습목표
- 유닉스 시스템V에서 제공하는 IPC기법을 이해한다.
- 메시지 큐를 이용해 통신 프로그램을 작성할 수 있다.
- 공유 메모리를 이용해 통신 프로그램을 작성할 수 있다.
- 세마포어를 이용한 IPC기법을 배운다.
목차
1. 시스템 V IPC 기초
2. 시스템 V IPC 관련 명령
3. 메시지 큐
4. 공유 메모리
5. 세마포어
1. 시스템 V IPC 기초
시스템 V IPC
- 시스템 V 계열 유닉스에서 개발해 제공하는 프로세스 간 통신방법
- 메시지 큐, 공유 메모리, 세마포어
공통 요소
- 시스템 V IPC를 사용하기 위해서는 IPC 객체를 생성해야 함.
- IPC 객체를 생성하기 위해 공통적으로 사용하는 기본 요소는 키와 식별자
키 생성
- 키로 IPC_PRIVATE 지정
- ftok 함수로 키 생성
#include <sys/ipc.h>
key_t ftok(const char *path, int id);
IPC 공통 구조체
- IPC 객체를 생성하면 IPC 공통 구조체가 정의된다
2. 시스템 V IPC 관련 명령
시스템 V IPC 정보 검색 : ipcs 명령
시스템 V IPC의 정보를 검색하고 현재 상태 확인
-m : 공유 메모리에 관한 정보만 검색
-q : 메시지 큐에 관한 정보만 검색
-s : 세마포어에 관한 정보만 검색
-a : -b, -c, -o, -p, -t 옵션으로 검색하는 항목 모두 출력
-A : 전체 항목을 모드 검색
-b : 각 방법의 최댓값 검색
-c : IPC 객체를 생성한 사용자의 로그인명과 그룹명 검색
-D mtype : 메시지 큐에서 mtype으로 지정한 메시지만 검색
-i : 공유 메모리 세그먼트에 연결된 ISM의 개수 출력
-J : IPC 객체 생성자의 프로젝트명 출력
-o : 현재 사용되고 있는 정보 출력
-p : PID 정보 출력
-t : 시간 정보 출력
IPCS 명령 사용 예
1. 현재 동작 중인 IPC 객체가 하나도 없는 경우
2. -a 옵션 지정 시: 모든 항목 출력
시스템 V IPC 정보 삭제 : ipcrm
-m shmid : 공유 메모리 삭제
-q msqid : 메시지 큐 삭제
-s semid : 세마포어 삭제
-M shmkey : shmkey로 지정한 공유 메모리 삭제
-Q msgkey : msgkey로 지정한 공유 메모리 삭제
-S semkey : semkey로 지정한 공유 메모리 삭제
3. 메시지 큐
메시지 큐
- 파이프와 유사하나 파이프는 스트림 기반으로 동작하고 메시지 큐는 메시지 단위로 동작
- 각 메시지의 최대 크기는 제한되어 있음
- 각 메시지에는 메시지 유형이 있어 수신 프로세스는 어떤 유형의 메시지를 받을 것인지 선택 가능
메시지 큐 생성 : msgget()
- key : IPC_PRIVATE 또는 ftok로 생성한 키값
- msgflg : 플래그와 접근 권한 지정
- IPC_CREAT : 새로운 키면 식별자를 새로 생성
- IPC_EXCL : 이미 존재하는 키면 오류 발생
- 메시지 큐 식별자를 리턴(msqid_ds 구조체)
메시지 전송 : msgsnd()
- msqid : 메시지 큐 식별자
- msgp : 메시지 버퍼 주소
- msgsz : 메시지 버퍼 크기
- msgflg : 블록모드(0)/비블록 모드(IPC_NOWAIT)
- 메시지 버퍼 구조체
메시지 수신 : msgrcv()
- msqid : 메시지 큐 식별자
- msgp : 메시지 버퍼 주소
- msgsz : 메시지 버퍼 크기
- msgtyp : 읽어올 메시지 유형
- msgflg : 블록모드(0)/비블록모드(IPC_NOWAIT)
- msgtyp에 지정할 값
- 0 : 메시지 큐의 다음 메시지를 읽어온다.
- 양수 : 메시지 큐에서 msgtyp로 지정한 유형과 같은 메시지를 읽어온다.
- 음수 : 메시지의 유형이 msgtyp로 지정한 값의 절대값과 같거나 작은 메시지를 읽어온다.
메시지 제어 : msgctl()
- msqid : 메시지 큐 식별자
- cmd : 수행할 제어기능
- buf : 제어 기능에 사용되는 메시지 큐 구조체 주소
- cmd에 지정할 값
- IPC_RMID : 메시지 큐 제거
- IPC_SET : 메시지 큐 정보 중 msg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytes 값을 세번째 인자로 지정한 값으로 변경
- IPC_STAT : 현재 메시지 큐의 정보를 buf에 저장
- msqid_ds 구조체
4. 공유 메모리
공유 메모리
- 같은 메모리 공간을 두 개 이상의 프로세스가 공유하는 것
- 같은 메모리 공간을 사용하므로 이를 통해 데이터를 주고 받을 수 있음
공유 메모리 생성 : shmget()
- key : IPC_PRIVATE 또는 ftok로 생성한 키값
- size : 공유할 메모리 크기
- shmflg : 공유 메모리의 속성을 지정하는 플래그
- IPC_CREAT, IPC_EXCL
- 공유 메모리 식별자를 리턴(shmid_ds 구조체)
- shmid_ds 구조체
공유 메모리 연결 : shmat()
- shmid : 공유 메모리 식별자
- shmaddr : 공유 메모리를 연결할 주소
- shmflg : 공유 메모리에 대한 읽기/쓰기 권한
- 0(읽기/쓰기 가능), SHM_RDONLY(읽기 전용)
공유 메모리 연결 해제 : shmdt()
- shmaddr : 연결을 해제할 공유 메모리 주소
공유 메모리 제어 : shmctl()
- cmd : 수행할 제어기능
•IPC_RMID : 공유 메모리 제거
•IPC_SET : 공유 메모리 정보 내용 중 shm_perm.uid, shm_perm.gid, shm_perm.mode 값을 세번째 인자로 지정한 값으로 변경
•IPC_STAT : 현재 공유 메모리의 정보를 buf에 지정한 메모리에 저장
•SHM_LOCK : 공유 메모리를 잠근다.
•SHM_UNLOCK : 공유 메모리의 잠금을 해제한다.
5. 세마포어
세마포어
- 프로세스 사이의 동기를 맞추는 기능 제공
- 한 번에 한 프로세스만 작업을 수행하는 부분에 접근해 잠그거나, 다시 잠금을 해제하는 기능을 제공하는 정수형 변수
- 세마포어를 처음 제안한 에츠허르 데이크스트라가 사용한 용어에 따라 잠금함수는 p로 표시하고 해제함수는 v로 표시
세마포어 기본 동작 구조
- 중요 처리부분(critical section)에 들어가기 전에 p 함수를 실행하여 잠금 수행
- 처리를 마치면 v 함수를 실행하여 잠금 해제
p 함수의 기본 동작 구조
- sem의 초기값은 1
- sem이 0이면 다른 프로세스가 처리부분을 수행하고 있다는 의미이므로 1이 될 때까지 기다린다.
- sem이 0이 아니면 0으로 만들어 다른 프로세스가 들어오지 못하게 함
v 함수의 기본 동작 구조
세마포어 생성: semget(2)
- nsems : 생성할 세마포어 개수
- semflg : 세마포어 접근 속성 (IPC_CREAT, IPC_EXCL)
semid_ds 구조체
- sem_perm: IPC공통 구조체
- sem_base: 세마포어 집합에서 첫번째 세마포어의 주소
- sem_nsems: 세모포어 집합에서 세마포어 개수
- sem_otime: 세마포어 연산을 수행한 마지막시간
- sem_ctime: 세마포어 접근권한을 마지막으로 변경한 시간
- sem_binary: 세마포어 종류를 나타내는 플래그
sem 구조체
- 세마포어 정보를 저장하는 구조체
•semval : 세마포어 값
•sempid : 세마포어 연산을 마지막으로 수행한 프로세스 PID
•semncnt: 세마포어 값이 현재 값보다 증가하기를 기다리는 프로세스 수
•semzcnt: 세마포어 값이 0이 되기를 기다리는 프로세스 수
세마포어 제어 : semctl()
- semnum : 기능을 제어할 세마포어 번호
- cmd : 수행할 제어 명령
- ... : 제어 명령에 따라 필요시 사용할 세마포어
공용체 주소(선택사항)
cmd에 지정할 수 있는 값
- IPC_RMID, IPC_SET, IPC_STAT : 메시지 큐, 공유 메모리와 동일 기능
- GETVAL : 세마포어의 semval 값을 읽어온다.
- SETVAL : 세마포어의 semval 값을 arg.val로 설정한다.
- GETPID : 세마포어의 sempid 값을 읽어온다.
- GETNCNT, GETZNCNT : 세마포어의 semncnt, semzcnt 값을 읽어온다.
- GETALL : 세마포어 집합에 있는 모든 세마포어의 semval 값을 arg.array에 저장
- SETALL : 세마포어 집합에 있는 모든 세마포어의 semval 값을 arg.array의 값으로 설정
세마포어 연산: semop(2)
- sops : sembuf 구조체 주소
- nsops : sops가 가리키는 구조체 크기
'Computer Science > 유닉스프로그래밍' 카테고리의 다른 글
[유닉스 시스템 프로그래밍] Ch11. 소켓 프로그래밍 기초 (0) | 2020.12.09 |
---|---|
Pthread 개념 (0) | 2020.12.06 |
[유닉스 시스템 프로그래밍] Ch09. 파이프 (0) | 2020.11.23 |
[유닉스 시스템 프로그래밍] Ch08. 메모리 매핑 (0) | 2020.11.16 |
[유닉스 시스템 프로그래밍] Ch07. 시그널 (0) | 2020.11.04 |