메시지 큐를 이용해 우선순위가 있는 데이터를 주고받는 프로그램인데, 실행결과 예상과 다르게 출력됩니다.
26_3.c 에서 메시지 큐를 생성하고 우선순위와 데이터로 구성된 메시지를 보내고,
26_4.c 는 메시지 큐에서 우선순위가 높은 메시지부터 읽어오게 하려고 그럽니다.
소스는 아래부분에 있습니다.
실행결과가 아래와 같이 나와야 제대로 동작하는 겁니다.
$26_3
input data -> Hello
input priority -> 7
input data -> Programming
input priority -> 3
input data -> Linux
input priority -> 5
input data -> quit
$26_4
data : Programming [3]
data : Linux [5]
data : Hello [7]
no message
그런데 실행결과가 아래와 같이 data와 priority 를 한번밖에 받질못하고 msgsnd failed : Identifier removed 라고 나옵니다.
$26_3
input data => Hello
input priority => 7
msgsnd failed: Identifier removed
소스에 이상이 있는지 잘 봐주시기 바랍니다.
아래는 26_3.c와 26_4.c 입니다.
-----------------------------------26_3.c-----------------------------
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define SIZE 124
/* 메시지 형식을 저장하는 type 멤버를 우선순위를 저장하는 용도로 사용한다. */
struct {
long type;
char data[SIZE];
} msg_data;
main()
{
int msqid, data_len;
char buffer[SIZE];
/* 1234 키의 메시지 큐 생성 */
if(msqid = msgget((key_t)1234, IPC_CREAT|0666) == -1) {
perror("msgget failed");
exit(1);
}
while(1) {
/* 표준입력장치로부터 데이터 입력 */
printf("input data => ");
scanf("%s", buffer);
/* 입력받은 내용이 ‘quit’이면 while 문 벗어남 */
if(!strcmp(buffer, "quit"))
break;
/* 표준입력장치로부터 우선순위 입력 */
printf("input priority => ");
scanf("%ld", &(msg_data.type));
strcpy(msg_data.data, buffer);
/* msg_data 메시지를 msqid 메시지 큐에 전송 */
if(msgsnd(msqid, &msg_data, strlen(msg_data.data), 0) == -1) {
perror("msgsnd failed");
exit(1);
}
}
exit(0);
}
------------------------------26_4.c-------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define SIZE 124
#define PRIOR 10 /* 우선순위 최대값 */
struct {
long type;
char data[SIZE];
} msg_data;
main()
{
int msqid, data_len;
/* 1234 키의 메시지 큐가 있으면 접근해서 식별자 받음 */
if(msqid = msgget((key_t)1234, IPC_CREAT|0666) == -1) {
perror("msgget failed");
exit(1);
}
while(1) {
/* (-1*PRIOR)에 의해 메시지 큐에서 메시지 형식 값이 작은 메시지부터 읽음.
IPC_NOWAIT에 의해 메시지 없으면 실패로 -1 반환하는데 이때의 errno는 ENOMSG */
if((data_len=msgrcv(msqid, &msg_data, SIZE, (-1*PRIOR), IPC_NOWAIT)) == -1) {
if(errno == ENOMSG) {
printf("no message\n");
break;
}
perror("msgrcv failed");
break;
}
msg_data.data[data_len]='\0';
printf("data : %s [%ld]\n", msg_data.data, msg_data.type);
}
/* msqid 메시지 큐 삭제 */
if(msgctl(msqid, IPC_RMID, 0) == -1) {
perror("msgctl failed");
exit(1);
}
exit(0);
}
저도....
이책 보고 있었는데 똑같은 에러가 발생하네요
좀 오래된 질문인데 답변이 없네요 ㅎㅎ
이건 프로그래밍 하다가 쉽게 저지를수 있는 문제인데요
if(msqid = msgget((key_t)1234, IPC_CREAT|0666) == -1)
이렇게 써주면 msqid에 0값이 들어가게 됩니다.
msgget()의 리턴값과 (예를 들면 65523 라고 한다면) -1을 비교한 다음 참인지 거짓인지 (거짓이니까 0이겠네요) msqid 값에 들어갑니다.
그렇게 되면 이 if 문은 무조건 else로 분기하게 됩니다. if (0)이니까요.
if((msqid = msgget((key_t)1234, IPC_CREAT|0666)) == -1) 로 바꾸시든가 아니면 msqid를 밖으로 빼주면 되겠네요 ㅎㅎㅎ
msgsnd()는 msgget으로 얻은 identifier 가 아닌 0 에 메세지를 쓰려고 하니 에러가 뜨는거겠죠 ㅋ
댓글 달기