본문으로 바로가기
homeimage
  1. Home
  2. 컴퓨터/프로그래밍
  3. C언어 메시큐 상태 정보·변경·삭제 함수 msgctl()

C언어 메시큐 상태 정보·변경·삭제 함수 msgctl()

· 댓글개 · 바다야크

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 입니다.
]$
SNS 공유하기
💬 댓글 개
최근글
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.