Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> Linux系統教程 >> Linux教程 >> linux消息隊列編程實例

linux消息隊列編程實例

日期:2017/2/7 14:29:17      編輯:Linux教程
 

前言:

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

函數:

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

原型:


int msgget(key_t key, int msgflg);

參數:

key:可以認為是一個端口號,也可以由函數ftok生成。

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

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

2.向隊列讀/寫消息

原型:

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


/*send.c*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#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]\n",errno,strerror(errno));
exit(-1);
}
}

while (1){
printf("input message type(end:0):");
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]\n",errno,strerror(errno));
exit(-1);
}
}
msgctl(msqid,IPC_RMID,0); //刪除消息隊列
}

消息接收端 receive.c


/*receive.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#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]\n",errno,strerror(errno));
sleep(2);
continue;
}
/*接收消息隊列*/
ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);
printf("text=[%s] pid=[%d]\n",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\n");
else if (cpid ==0) /*child process*/
childproc();
}
}

Copyright © Windows教程網 All Rights Reserved