linuxメッセージキューインスタンス

3802 ワード

前言:
メッセージキューは、メッセージのチェーンテーブルです.メッセージは、特定のフォーマットと特定の優先度を持つレコードと見なすことができます.メッセージキューに書き込み権限を持つプロセスは、一定のルールに従って新しいメッセージを追加できます.メッセージ・キューに読み取り権限があるプロセスは、メッセージ・キューからメッセージを読み出すことができます.
関数:
1.新しいメッセージキューの作成または既存のメッセージキューの取得
プロトタイプ:int msgget(key_t key,int msgflg);
パラメータ:
key:ポート番号と考えてもいいし、関数ftokで生成してもいいです.
     msgflg:IPC_CREAT値は、キューがない場合は新しい識別子を作成して返します.既に存在する場合は、元の識別子が返されます.             IPC_EXCL値は、キューがない場合は-1を返します.既に存在する場合は0を返します.
2.キューへのメッセージの読み取り/書き込み
プロトタイプ:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
パラメータ:
msqid:メッセージキューの識別コード
msgp:メッセージバッファへのポインタ.この位置は、送信および受信されたメッセージを一時的に格納するために使用され、ユーザー定義可能な汎用構造であり、形態は以下の通りである.
         struct msgstru 
         { long mtype; /*     ,   > 0 */ 
           char mtext[1]; /*      */ 
         };

msgsz:メッセージのサイズ.
msgtyp:メッセージキュー内から読み込まれたメッセージ形態.値がゼロの場合、メッセージキュー内のすべてのメッセージが読み出されます.msgflg:コアプログラムがキューにデータがない場合に取るべき行動を示すために使用されます.msgflgと定数IPC_の場合NOWAITが併用されると、msgsnd()実行時にメッセージキューがいっぱいになると、msgsnd()はブロックされず、すぐに-1に戻り、msgrcv()が実行されると、メッセージキューが空の場合、待機せずにすぐに-1に戻り、エラーコードをENOMSGに設定する.msgflgが0の場合、msgsnd()およびmsgrcv()は、キューがいっぱいまたは空の場合、ブロック待機の処理モードをとる.
3.メッセージキューのプロパティの設定
プロトタイプ:int msgctl(int msgqid,int cmd,struct msqid_ds*buf);
パラメータ:msgctlシステムはmsgqidに識別されたメッセージキューに対してcmd操作を実行するように呼び出し、システムは3種類のcmd操作を定義した:IPC_STAT , IPC_SET , IPC_RMID       IPC_STAT:メッセージキューに対応するmsqid_を取得するコマンドdsデータ構造をbufで指定したアドレス空間に保存します.      IPC_SET:このコマンドはメッセージキューのプロパティを設定するために使用され、設定するプロパティはbufに格納されます.     
      IPC_RMID:msqid識別メッセージキューをカーネルから削除します.
例:
/*receive.c */
#include 
#include 
#include 
#include 
#include 


#define MSGKEY 1024

struct msgstru
{
   long msgtype;
   char msgtext[2048];
};

/*   ,      */
void childproc(){
  struct msgstru msgs;
  int msgid,ret_value;
  char str[512];
  
  while(1){
     msgid = msgget(MSGKEY,IPC_EXCL );/*           */
     if(msgid < 0){
        printf("msq not existed! errno=%d [%s]
",errno,strerror(errno)); sleep(5); continue; } /* */ ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0); printf("text=[%s] pid=[%d]
",msgs.msgtext,getpid()); } return; } void main() { int i,cpid; /* create 5 child process */ for (i=0;i<5;i++){ cpid = fork(); if (cpid < 0) printf("fork failed
"); else if (cpid ==0) /*child process*/ childproc(); } }
/*send.c*/
#include 
#include 
#include 
#include 
#include 


#define MSGKEY 1024

struct msgstru
{
   long msgtype;
   char msgtext[2048]; 
};

main()
{
  struct msgstru msgs;
  int msg_type;
  char str[256];
  int ret_value;
  int msqid;

  msqid=msgget(MSGKEY,IPC_EXCL );  /*          */
  if(msqid < 0){
    msqid = msgget(MSGKEY,IPC_CREAT|0666);/*      */
    if(msqid <0){
	printf("failed to create msq | errno=%d [%s]
",errno,strerror(errno)); exit(-1); } } while (1){ printf("input message type[0=end process]:"); scanf("%d",&msg_type); if (msg_type == 0) break; printf("input message to be sent:"); scanf ("%s",str); msgs.msgtype = msg_type; strcpy(msgs.msgtext, str); /* */ ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT); if ( ret_value < 0 ) { printf("msgsnd() write msg failed,errno=%d[%s]
",errno,strerror(errno)); exit(-1); } } msgctl(msqid,IPC_RMID,0); // }