日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Linux进程间通信(IPC)-------消息队列

發布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux进程间通信(IPC)-------消息队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

消息隊列是進程間通信的一種方法,他有兩個操作,一個進程來發送消息(也就是向內存中寫入數據),另一個是獲取消息(也就是另外一個進程在內存中讀取數據)


下面來看消息隊列的

創建,寫入,讀取等需要用到的函數

創建:msgget((key_t) key,int msgflg)? ? ? ? ? 其中(key_t)key的話,我在管道,共享內存中都寫過,key值沒什么要求,大于零的32位整數就行,并且它是用來區分和別的消息隊列的,所以key值別和其他消息隊列重復就行

msgflg是個標志位,一般取IPC_CREAT :
如果消息隊列對象不存在,則創建之,否則則進行打開操作;下面附上幫助手冊

寫入數據(發送消息):int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg )

其中參數msqid就是上述創建的消息隊列的id? ?

struct msgbuf *msgp這玩意就是結構體指針? 該結構體就是消息體

msgsz就是消息體的大小

msgflg一般默認為0

讀取數據(讀取消息):size_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long type,int msgflg)

smqid就是創建的消息隊列id??

struct msgbuf *msgp? 結構體指針

size_t msgsz 就是存消息的大小

long type? 就是消息的類型

int msgflg標志位,一般默認0

下面附上幫助手冊:

上述那個結構體struct msgbuf就是消息體,type用來區分消息,你發送或者獲取消息的類型,其類型必須是long

下面的char 的數組就是發送或者獲取消息的最大內存(這里有一點要提一下,就是上面說到msgsnd中消息體大小,只算這個結構體中的char數組,龍不計算在內)

?下面來進行代碼實現:發送端的編寫

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是權限assert(msgid != -1);struct message me;me.type = 1;  //這塊將消息類型定義為1strcpy(me.buff,"hello"); //向buff中寫入hellomsgsnd(msgid,(void*)&me,32,0); //向消息隊列發送消息}

對獲取端的編寫:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是權限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,1,0); //消息存儲最多32  1是type類型  0是默認標志位printf("read msg:%s \n",me.buff);}

下面附上運行截圖(其中xiaoxi是發送消息,haha是獲取消息)? 那個已用字節數應該是32? ?因為xiaoxi這個發送端? 我剛剛運行了下 ,所以疊加起來就是64

?然后ipcs -q是查看消息隊列的使用情況的,鍵下面的4d2就是1234轉換為16進制的值

然后我們將發送消息的消息的類型值由1改為2,獲取端代碼不變,我們再來看一下結果

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是權限assert(msgid != -1);struct message me;me.type = 2;  //這塊將消息類型定義為1strcpy(me.buff,"hello"); //向buff中寫入hellomsgsnd(msgid,(void*)&me,32,0); //向消息隊列發送消息}

然后我們就會發現,獲取端獲取不了數據,一直在那塊阻塞,因為類型不對,寫入端寫的是2類型,讀取的是1類型

?因為類型不對,寫入端寫的是2類型,讀取的是1類型,所以肯定是讀取不了的,那么有沒有什么辦法讓它可以讀取呢,最笨的辦法就是將讀取端的消息類型改為2,這也是最常規的辦法,下面我來弄一個很有意思的方法:

? ? ? ? 將讀取端msgrcv的消息類型改為0,也就是默認類型,這樣的話,它就會接受所有的數據類型,下面我們來試一下:只改獲取端,發送端代碼不該,還是2類型

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是權限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,0,0); //消息存儲最多32  1是type類型  0是默認標志位printf("read msg:%s \n",me.buff);}

附上運行截圖:

?然后刪除消息隊列msgctl(msgid,IPC_RMID,NULL)

將該代碼寫到獲取端的末尾就好!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/msg.h>struct message
{long type;char buff[32];
};int main()
{int msgid = msgget((key_t)1234,IPC_CREAT|0600);//0600是權限assert(msgid != -1);struct message me;msgrcv(msgid,&me,32,0,0); //消息存儲最多32  1是type類型  0是默認標志位printf("read msg:%s \n",me.buff);if(msgctl(msgid,IPC_RMID,NULL) == -1)   //這塊msgctl中的那個NULL參數還沒搞明白  下次課過去問一下老師在評論區補一下{printf("delete error");}}

這樣執行下來就可以在程序執行完成之后,刪除消息隊列!

“加油呀? 兄弟們? BAT? 我來了”

總結

以上是生活随笔為你收集整理的Linux进程间通信(IPC)-------消息队列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。