반응형

msgsnd(2)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msgsnd(2)는 message queue로 데이터를 전송하는 함수입니다. 하나의 message queue의 크기는 msgctl(2)의 struct msqid_ds의 member 변수인 msg_qbytes바이트입니다. msg_qbytes값은 default로 MSGMNB byte로 설정되며 root 권한이 있는 경우에는 msgctl(2)을 이용하여 변경가능합니다.

 

전송하는 데이터는 아래와 같은 형태로 구성해야합니다. 구조체 이름 및 format은 마음대로 정의할 수 있으며, 첫번째를 long type을 선언하기만 하면 됩니다.

struct msgbuf 
{
   long mtype;       /* message type, must be > 0 */
   char mtext[];     /* message data */
};


예)
/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];
	......
};

struct my_msgbuf {
   long mtype;          /* message type, must be > 0 */
   struct my_data body; /* message data */
};

---------------------------------------
또는 

struct my_msgbuf {
   long mtype;          /* message type, must be > 0 */
   char data1[100];
	......
};

 

파라미터

msqid
    - msgget(2)가 return한 Message Queue ID 
mmsgp
    - 전송을 message 데이터
    - message 데이터는 첫번째가 반드시 long type의 message type이 있어야 하며, 
      그 이후에는 struct 또는 char 배열 등 원하는 format을 정의해서 사용합니다.

struct msgbuf 
{
   long mtype;
   char data[1000];
};

/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];
    /*
        ......
    */
};

struct msgbuf 
{
   long mtype;
   struct my_data body;
};
msgsz
    - 전송하려는 데이터의 크기이며, 데이터의 크기에는 long type의 message type을 제외한 
      나머지 데이터의 size입니다.
msgflg
    - Message Queue로 message를 전송할 때의 설정값.

 0 : Message를 전송하려 할 때에 Message Queue에 충분한 공간이 없는 경우 
    (즉, msgrcv(2)호출이 안되어 message queue에 쌓을 수 없는 경우)에 
    충분한 공간이 확보되어 전송할 수 있을 때까지 대기합니다.

 IPC_NOWAIT : Message를 전송하려는 할 때에 Message Queue에 충분한 공간이 없으며, 
    block되지 않고 -1을 return하여 빠져나온다. errno는 EAGAIN으로 변경됩니다.

 

RETURN

0
    - 정상적으로 Message Queue에 전달이 되었습니다. 

   struct msqid_ds 구조체의 아래 멤버변수가 변경됩니다.
   msg_lspid : 현재 프로세스의 ID로 설정됩니다. 
   msg_qnum : 1증가합니다.
   msg_stime : 현재시간으로 설정됩니다.

-1
    - 오류가 발생하였으며, 상세한 오류는 errno에 저장됩니다.

 EAGAIN : msgflg가 IPC_NOWAIT이면서 Message Queue에 충분한 공간이 없어서 재시도하시오.
 EFAULT : msgp가 유효하지 않은 메모리 번지입니다.
 EIDRM  : msqid가 이미 삭제된 ID입니다.
 EINTR  : message queue로 전달중 signal이 발생하여 전달에 실패하였습니다.
 EINVAL : msqid가 유효하지 않거나, mtype이 양수가 아니거나, 
          msgsz가 0보다 작거나 MSGMAX보다 큽니다. 

 


활용 예제

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

/* 사용자 데이터 정의 하기 */
struct my_data
{
    char data1[100];
    /*
        ......
    */
};

struct msgbuf 
{
   long mtype;
   struct my_data body;
};

int main(int argc, char *argv[])
{
   int qid;
   int msgtype = 1;
   int msgkey;
   struct msgbuf msg;
   char send_data[100];
   char dir[256];

   /* Message Queue의 key를 생성합니다. */
   snprintf(dir, 256, "%s/msg_home", getenv("HOME"));

   msgkey = ftok(dir, 'M');

   /* Message Queue를 생성합니다. */
   if((qid = msgget(msgkey, IPC_CREAT | 0666)) == -1) {
       perror("msgget error");
	   return 1;
   }

   memset(&msg, 0x00, sizeof(msg));
   msg.mtype = msgtype;
 
   ......

   strncpy(msg.body.data1, send_data, 100);

   ......

   /* 전송하는 데이터의 크기는 mtype 부분은 빼고 body 부분의 크기입니다. */
   if (msgsnd(qid, (void *) &msg, sizeof(struct my_data), IPC_NOWAIT) == -1) {
       perror("msgsnd error");
       exit(1);
   }

   return 0;
}

 

반응형
블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

,