APUE學習之 程序通訊實現訊息佇列

2021-07-08 19:39:45 字數 3443 閱讀 9675

1.**實現

實現兩個程式之間通訊,乙個負責接收資料,並根據訊息的不同型別輸出不同的描述資訊。另乙個負責接收資料,傳送了從標準輸入的三種不同訊息。乙個標頭檔案定義兩個程式都需要的定義,最後用makefile檔案編譯得到兩個輸出檔案。

標頭檔案定義:

#define tokpath "/tmp/path.c"

#define tokid 'm'

#define msglen 512

#define megtype_1 1

#define megtype_2 2

#define megtype_3 3

struct msg_strc;

接收函式:

#include#include#include#include#include#include#include "proto.h"

int main(int argc,char *argv)

if((msgid=msgget(key,ipc_creat|0644))< 0)

for(;;)

if(recbuf.mtype==1)

else if(recbuf.mtype==2)

else if(recbuf.mtype==3)

}if((msgctl(msgid,ipc_rmid,0))< 0)

exit(0);

}

傳送函式:

#include#include#include#include#include#include#include#include "proto.h"

int main(int argc,char *argv)

if((msgid=msgget(key,0))<0)

for(int i=1;i<4;++i)

} exit(0);

}

makefile:

cflags= -wall -std=gnu99  

objects=megsnd megrec

all:megsnd megrec

.phony : all

megsnd : megsnd.o

cc $(cflags) -o megsnd megsnd.o

megrec : megrec.o

cc $(cflags) -o megrec megrec.o

megsnd.o :megsnd.c proto.h

cc $(cflags) -o megsnd.o -c megsnd.c

megrec.o :megrec.c proto.h

cc $(cflags) -o megrec.o -c megrec.c

clean :

rm $(objects) *.o

執行結果:

bash-4.2$ ./megsnd 

jack

19910125

i'am a programmer

bash-4.2$ ./megrec 

this is a user name:jack

this is a user passwd:19910125

this is a user describe:i'am a programmer

在上面的makefile中,實現不夠簡介,下一步可以花時間來仔細學習下。

2.訊息佇列介紹

乙個或多個程序可向訊息佇列寫入訊息,而乙個或多個程序可從訊息佇列中讀取訊息,這種程序間通訊機制通常使用在客戶/伺服器模型中,客戶向伺服器傳送請求訊息,伺服器讀取訊息並執行相應請求。在許多微核心結構的作業系統中,核心和各元件之間的基本通訊方式就是訊息佇列。

linux中的訊息可以被描述成在核心位址空間的乙個內部鍊錶,每乙個訊息佇列由乙個ipc的標識號唯一的標識。linux 為系統中所有的訊息佇列維護乙個 msgque 鍊錶,該鍊錶中的每個指標指向乙個 msgid_ds 結構,該結構完整描述乙個訊息佇列。

1.1建立函式

#include #include #include int msgget(key_t key, int msg***);

msgget 函式的作用是建立乙個訊息佇列,訊息讀列是雙工的,兩邊都可以讀寫。

引數列表:

key 通訊的鍵值,擁有相同 key 的雙方才可以通訊。

key 值必須是唯一的,系統中有個 ftok(3) 函式可以用於獲取 key,通過檔案 inode 和 salt 進行 hash 運算來生成唯一的 key,只要兩個程序使用相同的檔案和 salt 就可以生成一樣的 key 值了。

msg***:特殊要求。無論有多少特殊要求,只要使用了 ipc_creat,就必須按位或乙個許可權。

同乙個訊息佇列只需要建立一次,所以誰先執行起來誰有責任建立訊息佇列,後執行起來的就不需要建立了。

同理,對於後啟動的程序來說,訊息佇列不是它建立的,那麼它也沒有必要銷毀了。

1.2傳送和接收函式

#include #include #include int msgget(key_t key, int msg***);

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

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

struct msgbuf ;

msgrcv 函式從 msgid 這個訊息佇列中接收資料,並將接收到的資料放到 msgp 結構體中,這段空間有 msgz 個位元組大小,msgz 的值要減掉強制的成員 mtype 的大小(sizeof(long))。

msgtyp 是 msgp 結構體中的 mtype 成員,表示要接收哪種型別的訊息。雖然 msg 是訊息佇列,但是它並不完全遵循佇列的形式,可以讓接收者挑訊息接收。如果不挑訊息可以填寫 0,這樣就按照佇列中的訊息順序返回。msfglg 是特殊要求位圖,沒有寫0。

msgsnd函式向 msgid 這個訊息佇列傳送 msgp 結構體資料,msgp 的大小是 msgsz,msg*** 是特殊要求,沒有特殊要求可以寫 0。 

1.3訊息佇列控制函式

#include #include #include int msgctl(int msqid, int cmd, struct msqid_ds *buf);

通過 cmd 指定具體的命令,然後通過 buf 為 cmd 命令設定引數,當然有些命令是需要引數的,有些命令則不需要引數。

最常用的 cmd 就是 ipc_rmid,表示刪除(結束)某個 ipc 通訊,並且這個命令不需要 buf 引數,直接傳入 null 即可。

APUE學習之 程序通訊fifo實現管道

一.fifo介紹 fifo函式用於建立命名管道,作用與匿名管道相同,不過可以在不同的程序之間使用,相當於對乙個普通檔案進行讀寫操作就可以了。這個管道檔案是任何有許可權的程序都可以使用的,兩端都像操作乙個普通檔案一樣對它進行開啟 讀寫 關閉動作就可以了,只要一端寫入資料另一端就可以都出來。includ...

程序間通訊實現

程序之間資料是相互隔離的,要想實現程序間的通訊 ipc機制 就必須借助於一些技術才可以,比如multiprocessing模組中的 佇列和管道,這兩種方式都是可以實現程序間資料傳輸的,由於佇列是管道 鎖的方式實現,所以著重研究佇列即可 建立共享的程序佇列,queue是多程序安全的佇列,可以使用que...

Linux訊息佇列實現程序間通訊例項詳解

linux訊息佇列實現程序間通www.cppcns.com信例項詳解 一 什麼是訊息佇列 訊息佇列提供了一種從乙個程序向另乙個程序傳送乙個資料塊的方法。每個資料塊都被認為含有乙個型別,接收程序可以獨立地接收含有不同型別的資料結構。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。但是訊息佇列與命名...