、什么是消息隊(duì)列
消息隊(duì)列提供了一種從一個(gè)進(jìn)程向另一個(gè)進(jìn)程發(fā)送一個(gè)數(shù)據(jù)塊的方法。 每個(gè)數(shù)據(jù)塊都被認(rèn)為是有一個(gè)類(lèi)型,接收者進(jìn)程接收的數(shù)據(jù)塊可以有不同的類(lèi)型值。我們可以通過(guò)發(fā)送消息來(lái)避免命名管道的同步和阻塞問(wèn)題。消息隊(duì)列與管道不同的是,消息隊(duì)列是基于消息的,而管道是基于字節(jié)流的,且消息隊(duì)列的讀取不一定是先入先出。消息隊(duì)列與命名管道有一樣的不足,就是每個(gè)消息的大長(zhǎng)度是有上限的(MSGMAX),每個(gè)消息隊(duì)列的總的字節(jié)數(shù)是有上限的(MSGMNB),系統(tǒng)上消息隊(duì)列的總數(shù)也有一個(gè)上限(MSGMNI)。

注:消息隊(duì)列、共享內(nèi)存和信號(hào)量都有一個(gè)共同的數(shù)據(jù)結(jié)構(gòu)。
二、函數(shù)
1、創(chuàng)建消息隊(duì)列或取得已存在的消息隊(duì)列
int msgget(key_t key, int msgflg);
參數(shù):
key:可以認(rèn)為是一個(gè)端口號(hào),也可以由函數(shù)ftok生成。
msgflg:
(1)IPC_CREAT 如果IPC不存在,則創(chuàng)建一個(gè)IPC資源,否則打開(kāi)操作。
(2)IPC_EXCL:只有在共享內(nèi)存不存在的時(shí)候,新的共享內(nèi)存才建立,否則就產(chǎn)生錯(cuò)誤。
如果單獨(dú)使IPC_CREAT,XXXget()函數(shù)要么返回一個(gè)已經(jīng)存在的共享內(nèi)存的操作符,要么返回一個(gè)新建的共享內(nèi)存的標(biāo)識(shí)符。
(3)如果將IPC_CREAT和IPC_EXCL標(biāo)志一起使用,XXXget()將返回一個(gè)新建的IPC標(biāo)識(shí)符;如果該IPC資源已存在,或者返回-1。
IPC_EXEL標(biāo)志本身并沒(méi)有太大的意義,但是和IPC_CREAT標(biāo)志一起使用可以用來(lái)保證
所得的對(duì)象是新建的,而不是打開(kāi)已有的對(duì)象。
2.向隊(duì)列讀/寫(xiě)消息
從消息隊(duì)列中取消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
將數(shù)據(jù)放到消息隊(duì)列中
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
參數(shù):
msqid:消息隊(duì)列的標(biāo)識(shí)碼
msgp:指向消息緩沖區(qū)的指針,此位置用來(lái)暫存發(fā)送和接受的消息,是一個(gè)用戶(hù)可定義的數(shù)據(jù)結(jié)構(gòu)。
struct msgstru{
long mtype; //大于0
char mtext[用戶(hù)指定大小];
};msgsz:消息的大小
msgtype:從消息隊(duì)列內(nèi)讀取消息的形態(tài),如果值為零,表示消息隊(duì)列中所有值都會(huì)被讀取。
msgflg:用來(lái)指明核心程序在隊(duì)列沒(méi)有數(shù)據(jù)的情況下所應(yīng)采取的行動(dòng)
(1)如果msgflg和常數(shù)IPC_NOWAIT合用,則在msgsnd()執(zhí)行時(shí)若是消息隊(duì)列已滿(mǎn),則msgsnd()將不會(huì)阻塞,會(huì)立即返回-1。
(2)如果執(zhí)行的是msgrcv(),則在消息隊(duì)列呈空時(shí),不做等待馬上返回-1。
(3)當(dāng)msgflg為0時(shí),msgsnd()及msgrcv()在隊(duì)列呈滿(mǎn)或呈空的情形時(shí),采取阻塞等待的處理模式。
3.設(shè)置消息隊(duì)列屬性
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
參數(shù):
msgctl 系統(tǒng)調(diào)用對(duì) msgqid 標(biāo)識(shí)的消息隊(duì)列執(zhí)行 cmd 操作,系統(tǒng)定義了 3 種 cmd 操作(1)IPC_STAT : 該命令用來(lái)獲取消息隊(duì)列對(duì)應(yīng)的 msqid_ds 數(shù)據(jù)結(jié)構(gòu),并將其保存到 buf 指定的地址空間。
(2) IPC_SET : 該命令用來(lái)設(shè)置消息隊(duì)列的屬性,要設(shè)置的屬性存儲(chǔ)在buf中。
(3) IPC_RMID : 從內(nèi)核中刪除 msqid 標(biāo)識(shí)的消息隊(duì)列。
例子:
comm.h
#pragma once
#include<sys/types.h>
#include<sys/ipc.h>
#include<stdio.h>
#include<sys/msg.h>
#include<string.h>
#define _PATH_NAME_ "/tmp"
#define _PROJ_ID_ 0x6666
#define _SIZE_ 1024
extern int serve_type;
extern int client_type;
struct msgbuf
{
long mtype;
char mtext[_SIZE_];
};
int create_msg_queue();
int get_msg_queue();
void destory_msg_queue(int msg_id);
void recv_msg_queue(int msg_id,char* out,int _type);
int create_msg_queue();
void send_msg_queue(int msg_id,const char*msg,int _type);comm.c
#include"comm.h"
#include<stdio.h>
#include<error.h>
#include<sys/msg.h>
#include<string.h>
#include"comm.h"
int serve_type=1;
int client_type=2;
static int comm_msg_queue(int flag)
{
key_t _key = ftok(_PATH_NAME_,_PROJ_ID_);
if(_key<0)
{
perror("ftok");
return -1;
}
int msg_id = msgget(_key,IPC_CREAT | IPC_EXCL);
if(msg_id < 0)
{
perror("msgget");
return -2;
}
return msg_id;
}
int create_msg_queue()
{
int flag = IPC_CREAT | IPC_EXCL|0666;
return comm_msg_queue(flag);
}
int get_msg_queue()
{
int flag = IPC_CREAT;
return comm_msg_queue(flag);
}
void destory_msg_queue(int msg_id)
{
if(msgctl(msg_id,IPC_RMID,NULL)<0)
{
perror("msgctl");
}
}
void send_msg_queue(int msg_id,const char*msg,int _type)
{
struct msgbuf data;
memset(data.mtext,'\0',sizeof(data.mtext));
data.mtype = _type;
strcpy(data.mtext,msg);
if(msgsnd(msg_id,&data,sizeof(data.mtext),0)<0)
{
perror("msgsnd");
}
}
void recv_msg_queue(int msg_id,char* out,int _type)
{
struct msgbuf data;
memset(data.mtext,'\0',sizeof(data.mtext));
data.mtype = _type;
if(msgrcv(msg_id,&data,sizeof(data.mtext),_type,0)<0)
{
perror("msgrcv");
}
else
{
strcpy(out,data.mtext);
}
}serve.c
#include"comm.h"
int main()
{
int msg_id = create_msg_queue();
if(msg_id < 0)
{
perror("msgget");
return 0;
}
int done = 0;
char buf[_SIZE_];
while(!done)
{
memset(buf,'\0',sizeof(buf));
recv_msg_queue(msg_id,buf,client_type);
printf("client#",buf);
printf("Please Enter#");
fflush(stdout);
ssize_t _s=read(0,buf,sizeof(buf)-1);
if(_s > 0)
{
buf[_s]='\0';//bug
}
send_msg_queue(msg_id,buf,serve_type);
}
destory_msg_queue(msg_id);
return 0;
}client.c
#include"comm.h"
int main()
{
int msg_id = get_msg_queue();
int done = 0;
char buf[_SIZE_];
while(!done)
{
printf("Please Enter#");
fflush(stdout);
ssize_t _s=read(0,buf,sizeof(buf)-1);
if(_s > 0)
{
buf[_s]='\0';//bug
}
send_msg_queue(msg_id,buf,client_type);
memset(buf,'\0',sizeof(buf));
recv_msg_queue(msg_id,buf,serve_type);
printf("serve#%s",buf);
}
destory_msg_queue(msg_id);
return 0;
}另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線(xiàn),公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁(yè)名稱(chēng):進(jìn)程通信——消息隊(duì)列-創(chuàng)新互聯(lián)
標(biāo)題來(lái)源:http://chinadenli.net/article46/cosjhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、網(wǎng)站營(yíng)銷(xiāo)、標(biāo)簽優(yōu)化、建站公司、App設(shè)計(jì)、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容