[UNIX] 시스템 V IPC

Taegang Yun·2023년 12월 9일
1

Unix 프로그래밍

목록 보기
15/19

시스템 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");


}
profile
언젠간 전문가가 되겠지

0개의 댓글