linux进程间通信:消息队列实现双端通信
生活随笔
收集整理的這篇文章主要介紹了
linux进程间通信:消息队列实现双端通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
雙端通信描述
利用消息隊列針對發送接受消息的類型唯一性 進行多個客戶端之間消息傳遞,而不需要server端進行消息轉發。
同時消息隊列的讀阻塞和寫阻塞特性(消息隊列中已經寫入數據,如果再不讀出來,則無法再次寫入)讓消息隊列的實現過程只能如下:
- 客戶端1的父進程用來處理類型1的消息寫,子進程處理類型2的消息讀
- 客戶端2的父進程處理類型2的消息寫,子進程處理類型1的消息讀
實現
客戶端1 client1.c
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define MSG_TYPE1 1
#define MSG_TYPE2 2 struct msgbuf
{long mtype;char mtext[100];
};int main()
{//當多用戶的時候通過指定文件以及設置id來獲取唯一的key標識//key_t key = ftok(".",100);key_t key = 12345; //個人使用的時候可以直接指定key//創建msg_qid的對象int msg_qid = msgget(key, IPC_CREAT | 0666);struct msgbuf msg1,msg2;int ret;char send_buf[100],rcv_buf[100];ret = fork();if ( -1 == ret ) {printf("fork failed! \n");_exit(-1);}//子進程處理消息1的寫else if (ret == 0) {while(1) {memset(&msg1, 0 , sizeof(msg1));//初始化消息類型以及消息內容scanf("%s",msg1.mtext);msg1.mtype = MSG_TYPE1;//發送消息到消息標識的msg_qid IPC 對象中/* if( -1 == msgsnd(msg_qid,(void *)&msg1,strlen(msg1.mtext),0)) {printf("send msg1 failed\n");_exit(-1);}*/msgsnd(msg_qid,(void *)&msg1,strlen(msg1.mtext),0);}}//父進程處理消息2的讀else {while(1) { memset(&msg2, 0, sizeof(msg2));//獲取消息大小為sizeof(msg2.mtext)if (-1 == msgrcv(msg_qid,(void*)&msg2,sizeof(msg2.mtext),MSG_TYPE2,0)){printf("receive msg2 failed\n");_exit(-1);} printf("client1:%s\n",msg2.mtext);}}msgctl(msg_qid,IPC_RMID,NULL);return 0;
}
客戶端2 client2.c
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define MSG_TYPE1 1
#define MSG_TYPE2 2 struct msgbuf
{long mtype;char mtext[100];
};int main()
{//當多用戶的時候通過指定文件以及設置id來獲取唯一的key標識//key_t key = ftok(".",100);key_t key = 12345; //個人使用的時候可以直接指定key//創建msg_qid的對象int msg_qid = msgget(key, IPC_CREAT | 0666);struct msgbuf msg1,msg2;int ret;ret = fork();if ( -1 == ret ) {printf("fork failed! \n");_exit(-1);}else if (ret == 0) {while(1) {memset(&msg1, 0 , sizeof(msg1));//初始化消息類型以及消息內容scanf("%s",msg1.mtext);msg1.mtype = MSG_TYPE2;//發送消息到消息標識的msg_qid IPC 對象中/*if( -1 == msgsnd(msg_qid,(void *)&msg1,strlen(msg1.mtext),0)) {printf("send msg1 failed\n");_exit(-1);}*/msgsnd(msg_qid,&msg1,100,0);}}else {while(1) { memset(&msg2, 0, sizeof(msg2));if (-1 == msgrcv(msg_qid,(void*)&msg2,sizeof(msg2.mtext),MSG_TYPE1,0)){printf("receive msg2 failed\n");_exit(-1);} printf("client2:%s\n",msg2.mtext);}}msgctl(msg_qid,IPC_RMID,NULL);return 0;
}
編譯運行輸出如下:
消息隊列相關命令
ipcs -q 查看系統消息隊列
ipcrm -q msqid 按照消息標識刪除當前用戶下的消息隊列
ipcmk -Q創建消息隊列
消息隊列相比于fifo的主要差異
差異:
- 消息的改變,每個消息都有自己的身份標識
- 內核提供訪問消息結構的接口,并且提供結構來動態修改消息結構
共同點:
消息的接受和發送都是阻塞讀和阻塞寫,即需要將寫的內容讀出,否則下次發送會阻塞寫
總結
以上是生活随笔為你收集整理的linux进程间通信:消息队列实现双端通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 是谁九色鹿是谁画的啊?
- 下一篇: linux进程间通信:system V