歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> linux 消息隊列實例

linux 消息隊列實例

日期:2017/3/3 12:50:48   编辑: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:指向消息緩沖區的指針,此位置用來暫時存儲發送和接收的消息,是一個用戶可定義的通用結構,形態如下:

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 © Linux教程網 All Rights Reserved