程序間通訊之訊息佇列

2021-08-17 09:49:12 字數 3985 閱讀 7647

訊息佇列

上篇文章已經介紹過了管道(今天來看下程序間通訊的另一種方式——訊息佇列。

首先來看下訊息佇列的一些基礎概念:

1.訊息佇列提供了從乙個程序向另乙個程序傳送一塊資料的方法

2.每個資料塊被認為有乙個型別,接收者程序接受的資料塊可以有不同的型別值

3.訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(msgmax),每個訊息佇列的總的位元組數是有上限的(msgmnb),系統上訊息佇列的總數也有乙個上限(msgmni)

ipc物件資料結構(/usr/include/linux/ipc.h):

訊息佇列資料結構(/usr/include/linux/msg.h):

訊息佇列在記憶體中的表示:

訊息佇列函式

mssget函式

功能:用來建立和訪問乙個訊息佇列

原型:

int msgget(key_t key,int msg***);
引數:

key:某個訊息佇列的名字(呼叫ftok()函式:key_t ftok(const char *pathname,int proj_id))

·自己了解一下ftok()函式:

ipc_creat:若已有訊息佇列,直接返回;若無,則建立訊息佇列

ipc_creat and ipc_excl:若已有訊息佇列,則報錯;若無,則建立並返回(成功返回一定是建立了新的訊息佇列)

單獨的ipc_excl:無意義

返回值:成功返回非負整數,即該訊息佇列的標識碼;失敗返回-1

msgctl函式

功能:訊息佇列的控制函式

原型:

int msgctl(int msqid,int cmd,struct msqid_ds *buf)
引數:

msqid:由msgget函式返回的訊息佇列標識碼

cmd:是將要採取的動作(有三個可取值)

·cmd取值如下:

命令說明

ipc_stat

把msqid_ds結構中的資料設定為訊息佇列的當前關聯值

ipc_set

在程序有足夠許可權的前提下,把訊息佇列的當前關聯值設定為msqid_ds資料結構中給出的值

ipc_rmid

刪除訊息佇列

返回值:成功返回0,失敗返回-1

msgsnd函式

功能:把一條訊息新增到訊息佇列中

原型:

int msgsnd(int msqid,const void *msgp,size_t msgsz,int msg***)
引數:

msqid:由msgget函式返回的訊息佇列標識碼

msgp:是乙個指標,指標指向準備傳送的訊息

msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息型別的那個long int長整型

ms***:控制著當前訊息佇列滿或到達系統上限時將要發生的事情(預設取0)

ms***=ipc_nowait表示佇列滿不等待,返回eagain錯誤

返回值:成功返回0,失敗返回-1

msgrcv函式

功能:是從乙個訊息佇列接收資訊

原型:

ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msg***)
引數:

msqid:由msgget函式返回的訊息佇列標識碼

msgp:是乙個指標,指標指向準備傳送的訊息

msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息型別的那個long int長整型

msgtyp:它可以實現接受優先順序的簡單形式

msg***:控制著佇列中沒有相應型別的訊息可供接收時將要發生的事

返回值:成功返回實際放到接收緩衝區裡去的字元個數,失敗返回-1

例項:makefile

.phony:all

all:client server

client:client.c comm.c

gcc -o $@ $^

server:server.c comm.c

gcc -o $@ $^

.phony:clean

clean:

rm -f client server

comm.h

#ifndef _comm_h_

#define _comm_h_

#include #include #include #include #define pathname "."

#define proj_id 0x7777

#define server_type 1

#define client_type 2

struct msgbuf;

int createmsgqueue();

int getmsgqueue();

int destroymsgqueue();

int sendmsg();

int recvmsg();

#endif

comm.c

#include "comm.h"

static int commmsgqueue(int flags)

int msgid = msgget(_key,flags);

if(msgid < 0)

return msgid;

}int createmsgqueue()

int getmsgqueue()

int destroymsgqueue(int msgid)

return 0;

}int sendmsg(int msgid,int who,char *msg)

return 0;

}int recvmsg(int msgid,int recvtype,char out)

strcpy(out,buf.mtext);

return 0;

}

server.c

#include "comm.h"

int main()

}destroymsgqueue(msgid);

return 0;

}

client.c

#include "comm.h"

int main()

recvmsg(msgid,server_type,buf);

printf("server# %s\n",buf);

}return 0;

}

測試結果:

ipcs & ipcrm 命令

·ipcs  顯示ipc資源

·ipcrm  手動刪除ipc資源

總結:訊息佇列的生命週期隨核心(除非通過命令或介面刪除)

程序間通訊之訊息佇列

include include define max msg buf len 512 int ikey 6004 struct ipcmsgbuf int main void 寫訊息佇列 memset msgdata,0,sizeof struct ipcmsgbuf msgdata.mtype 1...

程序間通訊之訊息佇列

訊息佇列其實就是提供了一種從乙個程序向另乙個程序傳送乙個資料塊的方法。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。此外,訊息佇列和管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列不一定是先入先出。訊息佇列與命名管道有一樣的不足,就是每個訊息的最大長度是有上限的 msgm...

程序間通訊之訊息佇列

訊息佇列 訊息佇列本質上是提供了一種從乙個程序向另乙個程序傳送資料快的方法。每個資料快都被認為是有乙個型別,接受者程序接收的資料塊可以有不同的型別值。訊息佇列和管道的區別 1 訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先進先出的。2 訊息佇列的生命週期是隨核心的 不隨程序...