leebaek

[UNIX 프로그래밍] 11-1강 메세지 큐 본문

수업 정리/UNIX 프로그래밍

[UNIX 프로그래밍] 11-1강 메세지 큐

leebaek 2024. 12. 14. 01:11

  • IPC 설비
  • IPC 객체 상태 구조
  • IPC 정보 검색 및 삭제
  • message passing
  • msgget 시스템 호출
  • msgsnd 시스템 호출
  • msgrcv 시스템 호출
  • message 송수신의 예
  • msgctl 시스템 호출

 IPC 설비

□ key

- message_queue, semaphore, shared memory segment에 대한 identifier ( file 이름에 해당 )

- 서로 다른 process들도 동일 IPC 객체는 같은 key 값으로 접근 가능함

- 시스템에서 unique한 key값을 사용하여야 함

 

□ key 값 생성

#include <sys/ipc.h>
key_t ftok(const char *path, int id);

 

- 해당 파일의 st_dev(파일이 위치한 장치 정보), st_ino(inode 번호)와 id로 key 값 생성


 IPC 객체 상태 구조

struct ipc_perm {
    uid_t cuid // 생성자의 uid
    gid_t cgid // 생성자의 gid
    uid_t uid // 소유자의 uid
    gid_t gid // 소유자의 gid
    mode_t mode // permission ( execution은 의미 없음 )
}

 

 

- IPC 객체는 file 처럼 실행권한의 의미가 없기 때문에 해당 비트는 무시됨


 IPC 정보 검색 및 삭제

□ ipc 관련 정보 검색

$ ipcs

 

□ ipc 삭제

$ ipcrm -m shmid
$ ipcrm -q msqid
$ ipcrm -s semid

 message passing

□ message queue

  • msgget : queue 생성
  • msgsnd : message 보내기
  • msgrcv : message 받기

msgget 시스템 호출

□ msgget()

#include <sys/msg.h>
int msgget(key_t, int permflags);

 

  • key : message queue의 key 값
  • permflags = queue에 대한 access permission
    • IPC_CREAT : 해당 queue가 없으면 생성, 있으면 기존 queue의 ID 반환
    • IPC_EXCL : 해당 queue가 존재하지 않는 경우만 성공, 아니면 -1 return
  • return 값 : 음수가 아닌 queue indentifier

 msgsnd 시스템 호출

□ msgsnd()

#include <sys/msg.h>
int msgsnd(int mqid, const void *message, size_t size, int flags);

 

  • mqid : message queue identifier
  • message의 주소 : 보낼 message가 저장된 주소
  • size : message의 크기
  • flags = IPC_NOWAIT
    • send가 불가능하면 즉시 return ( queue가 가득찬 경우 )
    • flag가 설정되지 않으면, 성공할 때 까지 blocking
  • return 값은 0, -1

message의 구조

struct mymsg {
    long mtype; // message type ( 양의 정수 )
    char mtext[SOMEVALUE]; // message 내용 ... mtype 멤버 이후론 어떤 값이 추가되어도 다 상관없음 
}

 

- long type의 정수 값을 갖는 mtype과 임의의 message의 내용으로 구성

- mtype은 메세지를 구분하거나 우선순위를 설정할 때 사용

- messgae의 size는 message 내용의 크기만 측정됨 -> sizeof(mtext)


 msgrcv 시스템 호출

□ msgrcv()

#include <sys/msg.h>
int msgrcv(int mqid, void *message, size_t size, long msg_type, int flags);

 

  • mqid : message queue identifier
  • message 주소 : 받은 message를 저장할 저장 장소의 주소
  • size : 준비된 저장 장소의 크기
  • msg_type
    • 0 : queue의 첫 message
    • > 0 : 해당 값을 갖는 첫 message
    • < 0 : mtype값이 절대값 보다 작거나 같은 것 중 최소 값을 갖는 첫 message
    • ex ) -3으로 설정, 메세지 큐에는 1, 2, 3, 4, 5가 존재한다고 하면
    • 3보다 작거나 같은 것 중 최소니까 1, 2, 3 이중 최소는 1
    • 1 중에서 제일 먼저 온 메세지를 받는다는 의미 !
  • flags = IPC_NOWAIT
    • receive가 불가능하면 즉시 return ( queue에 해당 msg가 없는 경우 )
    • return 값은 -1, errno = EAGAIN
    • flag가 설정되지 않으면 ( 0일 경우 ), 성공시 까지 blocking
  • flags = MSGNOERROR
    • message가 size보다 길면 초과분을 자름
    • flag가 설정되지 않으면 size 초과시 error
  • return 값
    • receive 성공 시 : 받은 message의 길이
    • 실패 시 -1
    • access permission 때문에 실패한 경우 errorno = EACCESS

 message  송수신의 예

struct q_entry {
    long mtype;  // 메시지 타입
    int mnum;    // 메시지 내용 (정수)
};
struct q_entry msg;

qid = msgget(0111, 0600|IPC_CREAT);
while( msgrcv(qid, &msg, sizeof(int), 1, 0) > 0 ) {
    msg.mtype = 2;
    msg.mnum = msg.mnum+8;
    msgsnd(qid, &msg, sizeof(int), 0);
}

 msgctl 시스템 호출

□ msgctl()

- message queue에 대한 정보 획득

- message queue 제거

#include <sys/msg.h>
int msgctl(int mqid, int command, struct msqid_ds *msq_stat);

 

  • mqid : message queue identifier
  • command =
    • IPC_STAT : msg queue의 상태 정보 확인
    • IPC_RMID : msg_queue 삭제

□ msqid_ds 구조

struct ipc_perm msg_perm; // 소유권
msgqnum_t msg_qnum; // msg 수
msglen_t msg_qbytes; // bytes의 수
pid_t msg_lspid; // last sender
pid_t msg_lrpid; // last receiver
time_t msg_stime; // last sending time
time_t msg_rtime; // last receipt time
time_t msg_ctime; // last s/r time