linux消息隊列編程實例

轉自:linux 消息隊列實例 linux

前言:

   消息隊列就是一個消息的鏈表。能夠把消息看做一個記錄,具備特定的格式以及特定的優先級。對消息隊列有寫權限的進程能夠向其中按照必定的規則添加新消息;對消息隊列有讀權限的進程則能夠從消息隊列中讀走消息
數據結構

函數:


1.建立新消息隊列或取得已存在消息隊列

原型:int msgget(key_t key, int msgflg);函數

參數:spa

     key:能夠認爲是一個端口號,也能夠由函數ftok生成。.net

     msgflg:IPC_CREAT值,若沒有該隊列,則建立一個並返回新標識符;若已存在,則返回原標識符。指針

                IPC_EXCL值,若沒有該隊列,則返回-1;若已存在,則返回0。code

2.向隊列讀/寫消息

原型:blog

msgrcv從隊列中取用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);隊列

msgsnd將數據放到消息隊列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);進程

參數:

     msqid:消息隊列的標識碼

     msgp:指向消息緩衝區的指針,此位置用來暫時存儲發送和接收的消息,是一個用戶可定義的通用結構,形態以下: 

struct msgstru{
    long mtype; //大於0
    char mtext[512];
};

     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 標識的消息隊列。

實例:

消息發送端:send.c

 1 /*send.c*/  
 2 #include <stdio.h>   
 3 #include <sys/types.h>   
 4 #include <sys/ipc.h>   
 5 #include <sys/msg.h>   
 6 #include <errno.h>   
 7 
 8 #define MSGKEY 1024   
 9   
10 struct msgstru  
11 {  
12    long msgtype;  
13    char msgtext[2048];   
14 };  
15   
16 main()  
17 {  
18   struct msgstru msgs;  
19   int msg_type;  
20   char str[256];  
21   int ret_value;  
22   int msqid;  
23   
24   msqid=msgget(MSGKEY,IPC_EXCL);  /*檢查消息隊列是否存在*/  
25   if(msqid < 0){  
26     msqid = msgget(MSGKEY,IPC_CREAT|0666);/*建立消息隊列*/  
27     if(msqid <0){  
28     printf("failed to create msq | errno=%d [%s]\n",errno,strerror(errno));  
29     exit(-1);  
30     }  
31   }   
32    
33   while (1){  
34     printf("input message type(end:0):");  
35     scanf("%d",&msg_type);  
36     if (msg_type == 0)  
37        break;  
38     printf("input message to be sent:");  
39     scanf ("%s",str);  
40     msgs.msgtype = msg_type;  
41     strcpy(msgs.msgtext, str);  
42     /* 發送消息隊列 */  
43     ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT);  
44     if ( ret_value < 0 ) {  
45        printf("msgsnd() write msg failed,errno=%d[%s]\n",errno,strerror(errno));  
46        exit(-1);  
47     }  
48   }  
49   msgctl(msqid,IPC_RMID,0); //刪除消息隊列   
50 }  

消息接收端 receive.c

 1 /*receive.c */  
 2 #include <stdio.h>   
 3 #include <sys/types.h>   
 4 #include <sys/ipc.h>   
 5 #include <sys/msg.h>   
 6 #include <errno.h>   
 7   
 8 #define MSGKEY 1024   
 9   
10 struct msgstru  
11 {  
12    long msgtype;  
13    char msgtext[2048];  
14 };  
15   
16 /*子進程,監聽消息隊列*/  
17 void childproc(){  
18   struct msgstru msgs;  
19   int msgid,ret_value;  
20   char str[512];  
21     
22   while(1){  
23      msgid = msgget(MSGKEY,IPC_EXCL );/*檢查消息隊列是否存在 */  
24      if(msgid < 0){  
25         printf("msq not existed! errno=%d [%s]\n",errno,strerror(errno));  
26         sleep(2);  
27         continue;  
28      }  
29      /*接收消息隊列*/  
30      ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);  
31      printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid());  
32   }  
33   return;  
34 }  
35   
36 void main()  
37 {  
38   int i,cpid;  
39   
40   /* create 5 child process */  
41   for (i=0;i<5;i++){  
42      cpid = fork();  
43      if (cpid < 0)  
44         printf("fork failed\n");  
45      else if (cpid ==0) /*child process*/  
46         childproc();  
47   }  
48 }  
49     
相關文章
相關標籤/搜索