데이터를 전송할 메시지 큐를 만든다.
snd_queue = msgget((key_t)snd_key, IPC_CREAT | 0666);
rcv_queue = msgget((key_t)rcv_key, IPC_CREAT | 0666);
메시지 큐로 데이터를 전송한다.
int msgsnd( int msqid, const void *msgp, size_t msgsz, int msgflg );
msqid
는 메시지 큐의 식별자이다.
msgp
는 전송 대상인 데이터이다.
ㅡmsgsz
: 위에 보듯 전송 데이터는 long
값을 첫번째에 가지고 있어, 원하는 데이터만 걸러낼 수 있다. 따라서, 데이터의 크기에 long 값이 반드시 들어가기 때문에 type을 나타내는 long크기는 제거한다.
msgflg
의 값을 이용하여 메시지 큐에 있는 자료 전송 실패시의 동작을 선택할 수 있다. 0은 큐에 공간이 생길 때까지 기다리는 것이고, IPC_NOWAIT은 큐에 공간이 없을때 바로 -1로 복귀하는 것을 의미한다.
if(-1 == msgsnd(snd_queue, &msg, sizeof(msg) - sizeof(long), IPC_NOWAIT)){
perror("msgsnd error: ");
}
메시지 큐로부터 데이터를 읽어온다.
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msgrcv(rcv_queue, &rcv_data, sizeof(msg) - sizeof(long), 0, IPC_NOWAIT);
msqp
는 수신한 데이터이다.
msgtyp
은 메시지 큐에 있는 데이터 중 어떤 데이터를 읽어 들일지에 대한 옵션으로, 0이면 큐의 첫번째 자료를 읽어 들이는 것이고, 양수일 경우, 양수로 지정한 값과 동일한 데이터 타입의 자료 중 첫번째를 읽어들인다. 음수일 경우, 음수 값을 절대 값으로 바꾼 후, 이 절대값과 같거나 가장 작은 데이터 타입의 데이터를 일어들인다.
msgflg
는 읽어 들이는 옵션으로, IPC_NOWAIT일 경우, 메시지 큐에 메시지 없으면 기다리지 않고 -1로 복귀한다.
메시지 큐의 현재 상태 정보를 알 수 있고, 변경하고 삭제할 수 있다.
int msgctl ( int msqid, int cmd, struct msqid_ds *buf )
msgctl(snd_queue, IPC_RMID, 0);
msgctl(rcv_queue, IPC_RMID, 0);
msqid
는 메시지 큐의 식별번호이다.
cmd
의 종류에는 3가지가 있는데 IPC_RMID는 메시지 큐를 삭제하는 명령이다. 이 때는 buffer가 필요없으므로 0으로 지정한다. IPC_STAT는 현재 상태를 buf에 저장하는 것이고, IPC_SET은 현재 상태를 buf 값으로 변경하는 것이다.
OS 3번째 과제에서 작성했던 코드가 해당 내용을 구현한 것이다. 시험 전에 코드 리뷰하기!
과제 내용과 코드는 공개하면 안되서 올리지 못한다! 호홍