Message queueの一般的な操作と例
6739 ワード
Message queueはSystem V IPCの三剣客の一人(それぞれmessage queue,semaphore,shared memory)であり、主に以下の4つの関数呼び出しから構成されている:(msgget,msgctl,msngsnd,msgrcv)
(1) msgsend.cxx(メッセージqueueを作成し、メッセージをカーネルのメッセージキューに送信)
(2) msgrcv.cxx(カーネルからメッセージを読み出し、最後にカーネルのmessage queueを削除)
(3)実行結果
(1) msgsend.cxx(メッセージqueueを作成し、メッセージをカーネルのメッセージキューに送信)
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include<stdio.h>
#include<iostream>
using namespace std;
#define BUF_SIZE 100
typedef struct {
long mtype;
char mtext[BUF_SIZE];
} msg_info;
key_t getkey()
{
key_t key = ftok("/home/kingoal",1);
if(key == -1)
{
perror("Error on create key");
exit(-1);
}
return key;
}
int create_msg_queue()
{
int msg_id;
key_t key = getkey();
msg_id = msgget(key, IPC_CREAT|0660);
if(msg_id == -1)
{
perror("msgget error");
exit(-1);
}
return msg_id;
}
int send_message(int msg_id,char* message)
{
int result;
msg_info MsgInfo;
memset(&MsgInfo,0,sizeof(msg_info));
MsgInfo.mtype = 10;
strcpy(MsgInfo.mtext, message);
result = msgsnd(msg_id,&MsgInfo,strlen(message)+1,0);
if(result == -1)
{
perror("Failed to send message");
}
return result;
}
int show_msg_queue_stat(int msg_id)
{
struct msqid_ds MsgQueueInfo;
int result;
result = msgctl(msg_id,IPC_STAT, &MsgQueueInfo);
if(result == -1)
{
perror("Error on message control");
exit(-1);
}
cout<<"============= Message Queue Info ============="<<endl;
cout<<"Effective user id: "<<MsgQueueInfo.msg_perm.uid<<endl;
cout<<"Effective user group id: "<<MsgQueueInfo.msg_perm.gid<<endl;
cout<<"Current numbers of bytes in message queue(non-standard): "<<MsgQueueInfo.msg_cbytes<<endl;
cout<<"Current numbers of message in the queue: "<<MsgQueueInfo.msg_qnum<<endl;
cout<<"=============================================="<<endl;
return result;
}
int main(int argc,char* argv[])
{
int msg_id = create_msg_queue();
send_message(msg_id,"Hello message queue");
show_msg_queue_stat(msg_id);
return 0;
}
(2) msgrcv.cxx(カーネルからメッセージを読み出し、最後にカーネルのmessage queueを削除)
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define BUF_SIZE 100
typedef struct {
long mtype;
char mtext[BUF_SIZE];
}msg_info;
int rcv_msg(int msg_id,int msg_type,char* msg)
{
int result;
msg_info MsgInfo;
result = msgrcv(msg_id,&MsgInfo,BUF_SIZE,msg_type,IPC_NOWAIT);
if(result == -1)
{
if( errno == ENOMSG)
return errno;
perror("Error on message receive");
exit(-1);
}
strcpy(msg,MsgInfo.mtext);
return result;
}
int main(int argc,char* argv[])
{
int result;
char message[BUF_SIZE];
int msg_type;
int msg_id;
if(argc != 3)
{
printf("Usage: %s msgid msg_type
", argv[0]);
return -1;
}
msg_type = atoi(argv[2]);
msg_id = atoi(argv[1]);
while(1)
{
result = rcv_msg(msg_id,msg_type,message);
if(result == ENOMSG)
break;
printf("Message: %s
",message);
memset(message,0,BUF_SIZE);
}
msgctl(msg_id,IPC_RMID,NULL);
return 0;
}
(3)実行結果
[kingoal@sunrise ~/dev/cxx]$ ./msgsend
============= Message Queue Info =============
Effective user id: 1001
Effective user group id: 1001
Current numbers of bytes in message queue(non-standard): 20
Current numbers of message in the queue: 1
==============================================
[kingoal@sunrise ~/dev/cxx]$ ./msgsend
============= Message Queue Info =============
Effective user id: 1001
Effective user group id: 1001
Current numbers of bytes in message queue(non-standard): 40
Current numbers of message in the queue: 2
==============================================
[kingoal@sunrise ~/dev/cxx]$ ./msgsend
============= Message Queue Info =============
Effective user id: 1001
Effective user group id: 1001
Current numbers of bytes in message queue(non-standard): 60
Current numbers of message in the queue: 3
==============================================
[kingoal@sunrise ~/dev/cxx]$ ./msgsend
============= Message Queue Info =============
Effective user id: 1001
Effective user group id: 1001
Current numbers of bytes in message queue(non-standard): 80
Current numbers of message in the queue: 4
==============================================
[kingoal@sunrise ~/dev/cxx]$ ./msgsend
============= Message Queue Info =============
Effective user id: 1001
Effective user group id: 1001
Current numbers of bytes in message queue(non-standard): 100
Current numbers of message in the queue: 5
==============================================
[kingoal@sunrise ~/dev/cxx]$ ipcs
Message Queues:
T ID KEY MODE OWNER GROUP
q 786432 22754234 --rw-rw---- kingoal kingoal
Shared Memory:
T ID KEY MODE OWNER GROUP
Semaphores:
T ID KEY MODE OWNER GROUP
[kingoal@sunrise ~/dev/cxx]$ main 786432 10
Message: Hello message queue
Message: Hello message queue
Message: Hello message queue
Message: Hello message queue
Message: Hello message queue
[kingoal@sunrise ~/dev/cxx]$