進程通信——消息隊列-創(chuàng)新互聯(lián)

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

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比樟樹網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式樟樹網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋樟樹地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。

注:消息隊列、共享內(nèi)存和信號量都有一個共同的數(shù)據(jù)結(jié)構(gòu)。

二、函數(shù)

1、創(chuàng)建消息隊列或取得已存在的消息隊列

int msgget(key_t key, int msgflg);

參數(shù):

 key:可以認為是一個端口號,也可以由函數(shù)ftok生成。
 msgflg:
(1)IPC_CREAT  如果IPC不存在,則創(chuàng)建一個IPC資源,否則打開操作。
(2)IPC_EXCL:只有在共享內(nèi)存不存在的時候,新的共享內(nèi)存才建立,否則就產(chǎn)生錯誤。

如果單獨使IPC_CREAT,XXXget()函數(shù)要么返回一個已經(jīng)存在的共享內(nèi)存的操作符,要么返回一個新建的共享內(nèi)存的標識符。

(3)如果將IPC_CREAT和IPC_EXCL標志一起使用,XXXget()將返回一個新建的IPC標識符;如果該IPC資源已存在,或者返回-1。
    IPC_EXEL標志本身并沒有太大的意義,但是和IPC_CREAT標志一起使用可以用來保證
所得的對象是新建的,而不是打開已有的對象。
2.向隊列讀/寫消息

從消息隊列中取消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int
msgflg);

將數(shù)據(jù)放到消息隊列中

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

參數(shù):

msqid:消息隊列的標識碼

msgp:指向消息緩沖區(qū)的指針,此位置用來暫存發(fā)送和接受的消息,是一個用戶可定義的數(shù)據(jù)結(jié)構(gòu)。

struct msgstru{
    long mtype; //大于0
    char mtext[用戶指定大小];
};

msgsz:消息的大小

msgtype:從消息隊列內(nèi)讀取消息的形態(tài),如果值為零,表示消息隊列中所有值都會被讀取。

msgflg:用來指明核心程序在隊列沒有數(shù)據(jù)的情況下所應(yīng)采取的行動

(1)如果msgflg和常數(shù)IPC_NOWAIT合用,則在msgsnd()執(zhí)行時若是消息隊列已滿,則msgsnd()將不會阻塞,會立即返回-1。

(2)如果執(zhí)行的是msgrcv(),則在消息隊列呈空時,不做等待馬上返回-1。

(3)當msgflg為0時,msgsnd()及msgrcv()在隊列呈滿或呈空的情形時,采取阻塞等待的處理模式。

3.設(shè)置消息隊列屬性

int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

參數(shù):

msgctl 系統(tǒng)調(diào)用對 msgqid 標識的消息隊列執(zhí)行 cmd 操作,系統(tǒng)定義了 3 種 cmd 操作(1)IPC_STAT : 該命令用來獲取消息隊列對應(yīng)的 msqid_ds 數(shù)據(jù)結(jié)構(gòu),并將其保存到 buf 指定的地址空間。
 (2) IPC_SET : 該命令用來設(shè)置消息隊列的屬性,要設(shè)置的屬性存儲在buf中。
 (3) IPC_RMID : 從內(nèi)核中刪除 msqid 標識的消息隊列。

例子:

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元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)頁名稱:進程通信——消息隊列-創(chuàng)新互聯(lián)
標題來源:http://muchs.cn/article46/cosjhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、網(wǎng)站營銷、標簽優(yōu)化、建站公司App設(shè)計、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計