메세지 큐는 어떤 공간이고, 프로세스들이 꺼내가는 우편함 같은 공간이다
메시지 큐 생성 > int msgget(key_t key, int msgflg);
returns queue id
key : 접근 키
msgflg : IPC_CREAT (있으면 그거 사용, 없으면 생성), IPC_EXL : 있으면 에러
ipcs -l 을 해보면
32000 system wide 이런게 뜨는데, 32000개의 큐를 만들 수 있다는 것. 거의 무제한이라고 생각해도 됨.
max size of msg >> 8192 한번에 보낼 수 있는 메세지 크기.
메세지 큐 제어 예제
EX03-15 )
./msgctl IPC_STAT 을 전달 (메큐 생성)
./msgctl IPC_RMID 를 전달 (메큐 제거)
id_msg = msgget((key_t) KEY,MSG, 0666, ;...) >>>> 커널 공간에 메세지 큐가 만들어지는 것
if(strcmpy(argv[1]), IPCSTAT) == 0 >> 넣어준 str command 가 저거인지?
ret = msgctl(id_msg, IPC_STAT, &dsbuf); >> dsbuf 에 메세지 큐에 대한 정보를 복사한다.
// 메세지 큐 정보 출력해보기....
}else { IPC_RMID 일 경우, 제거한다 }
==============
메세지 주입, 메세지 추출.
msgp -> 구조체로 만든 메세지의 메모리 주소를 넣는다. (메세지 구조체의 구성은 자유이다)
msgflg -> 똑같이 NONBLOCK 모드가 있음. 없을때 잠들지 않는 설정
msgsz -> long 타입의 크기를 빼고 전달해줘야 한다. ex) 만약 메세지 크기가68Byte라면, long mtype 의 크기를 빼고 mtext 의 크기만 전달해줘야 함. char mtext[64] 라면 64로 전달해야함
메세지 추출
msgrcv( msgid, *msgp
*msgp -> 구조체 주소 (보내는 놈과 받는놈이 같은 구조체를 쓰고, 어떤 구조체인지 알고 있는 것) // 메세지 구조는 자유이나, 첫번쨰 멤버만 long mtype으로 지정해줘야함.
msgflg 0 : 없으면 메세지 생길때까지 잠듦. IPC_NO_WAIT 모드면 메세지 없으면 바로 에러 반환.
msgtype : 0, 0 초과, 0 미만.
0: 큐에제일 먼저 들어온 메세지를 읽음 (큐는 FIFO)
0 초과 : mtype 이 msgtyp 과 같은 메세지 중 제일 먼저 들어온 메세지를 읽음. (먼저 들어올 메세지 지정)
0 미만: msgtyp의절대값보다 작거나 같은 메세지 중 제일 작은 mtype의 값을 읽음 (사실 순서는 큰 상관없고, x <= msgtyp 이하의 범위를 지정해주는 해위)
** (보통 공유하려는 용량에 따라 다르게 처리)
공유 메모리 : 큰 용량의 공유가 가능, but 많은 접근이 필요할 경우 세마포어 제어가 필요함 (더 많이 쓰임, 단점이 큰 단점이 아님)
메세지 큐 : 다대다 처리에 용이, but 메세지 자체가 크지 않기 때문에, 적은 데이터를 주고 받음. 또한, mtype 등의 세팅을 잘 하는 운영적인 측면이 필요. 쓰기에 조금 더 번거로움
***
EX03-15 >> msgsnd.c >> msg_buf msgarr[] -- 구조체의 메세지 배열
id_msg = msgget((key)KEY_MSG, 0666) >> 메세지 큐가 커널에 만들어짐.
for(i =0 l; i < sizeof(msgarr)/sizeof(msgarr[0]); i++){ >> 구조체 배열 요소의 갯수만큼 한번씩 다 전송해준다
ret = msgsnd(id_msg, (void *)&msgarr[i] (각 하나의 구조체 주소, 보이드 포인터 캐스팅은 아무 포인터나 가능하다는 뜻으로, 사실 안해도 됨), sizeof(struct msg_buf) (구조체의 크기) - sizeof(long) (long 변수만큼의 크기는 꼭 빼줘야함!), 0);
>>> 이 명령을 마치면 메세지 큐에 순서대로 10개가 들어가 있을 것임. 맨 먼저 들어간 1번이 제일 먼저 나갈 준비를 하고 있을 것.
>> 실행 후 넣을 떄는 mtype 도 같이 치면서 넣어주면 됨.
(수신하는 쪼ㅓㄱ)
---------
// msg 큐 간에 동기화 문제가 있을 수도 있음. (메세지 큐가 여러개 사용해야할 경우) > 자신의 mType 을 pid 로 설정해놓으면 좋음.