시스템 V IPC
- 유닉스는 크게 BSD 계열과 시스템 V 계열로 구분할 수 있다.
- 메시지 큐, 공유 메모리, 세마포어 세 개를 묶어 시스템 V IPC 라고 함
- 시스템 V IPC 를 사용하려면 IPC 객체를 생성해야 하는데 이를 위해 공통으로 사용하는 기본 요소가 키와 식별자
키와 식별자
- 키로 IPC_PRIVATE 지정
- IPC_PRIVATE를 키로 지정해 생성된 식별자를 서버와 클라이언트 모두 알 수 있게 생성
- fork() 함수로 생성된 부모-자식 프로세스 간 통신에서 유용하게 사용할 수 있다.
- ftok() 함수로 키 생성
- 키 생성의 주의사항
- 같은 키로 생성된 식별자는 통신에 사용할 수 있음
- 미리 정해진 키를 서버와 클라리언트 프로세스가 공유할 수 있게 해야 함.
- 헤더 파일이나 환경설정 파일에 키를 저장해 공유 가능.
키 생성하기 : ftok()
시스템 V IPC 정보 검색
- ipcs
- ipcs : 시스템 V IPC 의 정보를 검색하고 현재 상태를 확인하는 명령
- 일반 옵션 :
- -i id : id로 지정한 특정 요소에 대한 상세 정보를 출력, 이 옵션은 -m, -q, -s 중 하나와 결합해 사용
- -h : 도움말을 출력
- -V : 버전 정보를 출력
- 자원 옵션:
- -m : 공유 메모리 정보만 검색
- -q : 메시지 큐 정보만 검색
- -s : 세마포어 정보만 검색
- -a : 공유 메모리, 메시지 큐, 세마포어 모두의 정보를 검색, 이 옵션이 기본
- 출력 옵션:
- 출력 옵션은 하나만 지정. 여러 개 지정 시 마지막 옵션사용
- -c : IPC 자원을 생성한 사용자와 소유자 정보를 출력
- -l : 사용할 수 있는 메시지 큐, 공유 메모리, 세마포어의 제한값을 출력
- -p : 자원의 생성자와 마지막 운영자의 PID 를 출력
- -t : 시간 정보를 출력
- -u : 요약 정보를 출력
- 표현 형식 :
- -l 옵션에만 적용
- -b : 크기 정보를 바이트 단위로 출력
- —human “: 크기 정보를 사용자가 읽기 편한 형식으로 출력
- ipcmk 명령
- -M size : size에 지정한 바이트 크기로 공유메모리를 생성
- -Q : 메시지 큐를 생성
- -S number : number에 지정한 개수의 요소를 갖는 세마포어 생성
- -p mode : 자원의 접근 권한을 지정, 기본값은 0644
- ipcrm 명령
- -a : 모든 자원을 제거
- -M shmkey : shmkey로 생성한 공유 메모리의 마지막 연결이 해제된 후 공유 메모리를 제거
- -m shmid : shmid 로 지정한 공유 메모리를 삭제
- -Q msgkey : msgkey로 생성한 메시지 큐를 제거
- -q msgid : msgid로 지정한 메시지 큐를 삭제
- -S semkey : semkey로 생성한 세마포어를 삭제
- -s semkey : semid로 지정한 세마포어를 삭제
메시지 큐 식별자 생성 : msgget()
- 사용할 수 있는 플래그
- IPC_CREAT: 새로운 키면 식별자를 새로 생성
- IPC_EXCL : 이미 존재하는 키면 오류가 발생
- 메시지 큐 식별자와 관련된 메시지 큐와 IPC구조체가 새로 생성되는 경우
- key가 IPC_PRIVATE일 경우
- key가 IPC_PRIVATE가 아니며 key에 지정한 식별자와 관련된 다른 메시지 큐가 없고 플래그(msgflg)에 IPC_CREAT가 설정되어 있는 경우
key_t key;
int id;
key = ftok("keyfile", 1);
id = msgget(key, IPC_CREAT|0640);
메시지 전송 : msgsnd()
msgflg : 블록 모드(0) / 비블록 모드(IPC_NOWAIT)
struct mymsgbuf{
long mtype;
char mtext[80];
}
int main(){
key_t key;
int msgid;
struct mymsgbuf mesg;
key = ftok("keyfile", 1);
msgid = msgget(key, IPC_CREAT|0644);
mesg.mtype = 1;
strcpy(mesg.mtext, "Message Q Test");
msgsnd(msgid, (void *)&mesg, 80, IPc_NOWAIT);
}
메시지 수신 : msgrcv()
- 다섯 번째 인자인 msgflg에는 msgsnd() 함수처럼 블록 모드 / 비블록 모드를 지정
- msgflg가 IPC_NOWAIT 이면 메시지 큐가 비었을 때 기다리지 않고 즉시 오류를 리턴
- MSG_COPY : 메시지 큐에서 메시지를 복사해오고 원본은 큐에 그대로 둔다
- MSG_EXCEPT : msgtyp가 값이 양수일 때 지정한 유형과 다른 유형의 메시지 중 첫 번째 메시지를 가져옴
- MSG_NOERROR : 메시지가 msgsz에 지정한 바이트보다 크면 메시지 내용을 잘라냄.
int main(){
struct mymsgbuf inmsg;
key_t key;
int msgid, len;
key = ftok("keyfile", 1);
msgid = msgget(key, 0);
len = msgrcv(msgid, &inmsg, 80, 0, 0);
}
메시지 제어 : msgctl()
- msgid로 지정한 메시지 큐에서 cmd에 지정한 제어를 수행
- cmd 종류
- IPC_STAT : 현재 메시지 큐의 정보를 buf로 지정한 메모리에 저장
- IPC_SET: msg_perm.uid, gid, mode, qbytes를 지정한 값으로 변경
- IPC_RMID : msgid로 지정한 메시지 큐를 제거하고 관련된 데이터 구조체를 제거
- IPC_INFO : 메시지 큐의 제한값을 buf에 저장
int main(){
key_t key;
int msgid;
key = ftok("keyfile", 1);
msgid = msgget(key, IPC__CREAT|0644);
system("ipcs -q");
msgctl(msgid, IPC_RMID, NULL);
system("ipcs -q");
}