C함수 메시큐 상태 정보·변경·삭제 msgctl()
msgctl()은 메시지 큐의 현재 상태 정보를 구할 수 있고, 변경하거나 아예 메시지 큐를 삭제할 수 있습니다.
- 헤더: sys/types.h, sys/ipc.h, sys/msg.h
- 형태: int msgctl ( int msqid, int cmd, struct msqid_ds *buf )
- 인수: int msqid 메시지 큐 식별자
int cmd 제어 명령
struct msqid_ds *buf 메시지 큐 정보를 받을 버퍼 - 반환: 0 == 성공, -1 == 실패
msqid는 메시지 큐의 식별 번호입니다. 두 번째 인수인 cmd는 아래와 같은 명령입니다.
cmd | 의미 |
IPC_STAT | 메시지 큐의 현재 상태를 buf에 저장합니다. |
IPC_SET | 메시지 큐의 상태를 buf 값으로 변경합니다. 그러나 모든 정보는 안되고 msg_perm과 msg_qbytes 내용만 변경할 수 있습니다. |
IPC_RMID | 메시지 큐를 삭제합니다. 이럴 때에는 buf가 필요 없으므로 buf 를 0 으로 지정합니다. |
세 번째 인수인 buf 구조는 아래와 같습니다.
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue,unused */
struct msg *msg_last; /* last message in queue,unused */
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
unsigned long msg_lqbytes; /* ditto */
unsigned short msg_cbytes; /* current number of bytes on queue */
unsigned short msg_qnum; /* number of messages in queue */
unsigned short msg_qbytes; /* max number of bytes on queue */
__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_ipc_pid_t msg_lrpid; /* last receive pid */
};
C언어 msgctl() 함수 예제
예제에서는 두 개의 소스 파일이 있습니다. 하나는 main_sender.c로 메시지 큐로 데이터를 정송하는 것이고 또 하나는 main_receiver.c 로 메시지 큐에 있는 데이터 갯수를 확인하고 큐에 있는 데이터들을 가져옵니다.
메시지 큐의 특성 중 하나는 자료를 전송한 프로세스가 종료되더라도 메시지는 계속 유효하다는 것입니다. 그러므로 main_sender.c가 메시지 큐에 데이터를 전송한 후에 종료되도라도 메시지 큐에는 메시지가 계속 남아 있으며, main_receiver.c를 실행하여 메시지를 읽어 들일 수 있습니다.
/////////////////// main_receiver.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_SIZE 1024
typedef struct {
long data_type;
int data_num;
char data_buff[BUFF_SIZE];
} t_data;
int main( void)
{
int msqid;
t_data data;
struct msqid_ds msqstat;
int ndx;
if ( -1 == ( msqid = msgget( (key_t)1234, IPC_CREAT ¦ 0666))){
perror( "msgget() 실패");
exit( 1);
}
if ( -1 == msgctl( msqid, IPC_STAT, &msqstat)){
perror( "msgctl() 실패");
exit( 1);
}
printf( "메지시 개수는 %ld 입니다.\n", msqstat.msg_qnum);
for ( ndx = 0; ndx < msqstat.msg_qnum; ndx++){
if ( -1 == msgrcv( msqid, &data, sizeof( t_data) - sizeof( long), 0, 0)){
perror( "msgrcv() 실패");
exit( 1);
}
printf( "%d - %s\n", data.data_num, data.data_buff);
}
return 0;
}
/////////////////// main_sendedr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_SIZE 1024
typedef struct {
long data_type;
int data_num;
char data_buff[BUFF_SIZE];
} t_data;
int main( void)
{
int msqid;
int ndx = 0;
t_data data;
if ( -1 == ( msqid = msgget( (key_t)1234, IPC_CREAT ¦ 0666))){
perror( "msgget() 실패");
exit( 1);
}
// 메시지 3개만 전송하고 종료
for ( ndx = 1; ndx <= 3; ndx++){
data.data_type = 1;
data.data_num = ndx;
sprintf( data.data_buff, "type=%ld, ndx=%d, http://badayak.com", data.data_type, ndx);
if ( -1 == msgsnd( msqid, &data, sizeof( t_data) - sizeof( long), 0)){
perror( "msgsnd() 실패");
break;
}
printf( "메시지 %d번 전송\n", ndx);
}
// msgctl( msqid, IPC_RMID, 0);
}
C언어 msgctl() 예제 실행 결과
]$ gcc sender.c -o sender.out
]$ gcc receiver.c -o receiver.out
]$ ./sender.out
메시지 1번 전송
메시지 2번 전송
메시지 3번 전송
]$ ./receiver.out
메지시 개수는 3 입니다.
1 - type=1, ndx=1, http://badayak.com
2 - type=1, ndx=2, http://badayak.com
3 - type=1, ndx=3, http://badayak.com
]$
여기서 main_sender.c 의 하단에 있는 주석을 없애고 실행하면 어떻게 될까요?
]$ gcc sender.c -o sender.out
]$ ./sender.out
메시지 1번 전송
메시지 2번 전송
메시지 3번 전송
]$ ./receiver.out
메지시 개수는 3 입니다.
메지시 개수는 0 입니다.
]$
'컴퓨터 > 프로그래밍' 카테고리의 다른 글
C언어 공유 메모리 생성 함수 shmget() (0) | 2020.03.16 |
---|---|
C언어 메시지 큐로부터 데이터 수신 함수 msgrcv() (1) | 2020.03.16 |
C언어 메시지 큐로 데이터 전송 함수 msgsnd() (0) | 2020.03.16 |