1. 程式人生 > >程序通行(IPC)--實現訊息佇列及驗證

程序通行(IPC)--實現訊息佇列及驗證

今天我們來分享一下程序通行(IPC)-實現訊息佇列。

訊息佇列由作業系統提供一個連結串列(也就是說訊息佇列需要作業系統介面),以連結串列節點為一個數據塊(有型別),基於訊息,每條訊息有上限且訊息的總數也是有限的。

與管道通行的區別是,管道通訊以位元組流為通訊單位,訊息佇列是以有型別的資料塊為通訊單位。

訊息佇列實現原理:

一個程序建立訊息佇列(本文為serves),另一個程序(本文為client)開啟該訊息佇列即可。此後兩個程序可以相互讀寫以此來進行通訊。

訊息佇列實現步驟:

1》建立(開啟)訊息佇列

2》傳送訊息/接收訊息

3》接收訊息/傳送訊息

4》銷燬訊息佇列(誰建立誰銷燬)

進行傳遞訊息的資料塊(結構體)如下示:

  struct msgbuf{

      long mtype;//訊息的發起者的型別(標誌)

      char mtext[1024];//訊息內容

  };

訊息佇列是隨核心的,除了需要呼叫系統介面去建立訊息佇列,還需要呼叫系統介面去銷燬訊息佇列。

最後,介紹關於檢視訊息佇列和銷燬訊息佇列的系統命令,截圖如下:

 

程式碼和執行結果如下:

Commom.h

 #ifndef _COMMOM_H_
   #define _COMMOM_H_
   
   #include<stdio.h>
   #include<sys/types.h>
   #include<sys/ipc.h>
   #include<sys/msg.h>
   #include<string.h>
   #include<unistd.h>
  
  struct msgbuf{
      long mtype;
      char mtext[1024];
  };
  
  #define PATHNAME "."
  #define PROJ_ID 0x6666
  
  #define SERVE 1
  #define CLIENT 2
  
  int CreatMsgQueue();
  int GetMsgQueue();
  int SendMsgQueue(int msgid, int who, char* msg);
  int RecvMsgQueue(int msgid, int recvtype, char* out);
  int DestroyMsgQueue(int msgid);
  
  #endif

Commom.c

#include"commom.h"
 
   int commMsgQueue(int flags)
   {
       key_t keys = ftok(PATHNAME, PROJ_ID);
       if(keys<0){
           perror("ftok");
           return -2;
       }
 
      int msgid = msgget(keys, flags);
      if(msgid <0){
          perror("msgget");
          return -1;
      }
      return msgid;
  }
  
  int CreatMsgQueue()
  {
      return commMsgQueue(IPC_CREAT|IPC_EXCL);
  }
  int GetMsgQueue(){
      return commMsgQueue(IPC_CREAT);
  }
  int SendMsgQueue(int msgid, int who, char* msg){
      struct msgbuf buf;
      buf.mtype = who;
      strcpy(buf.mtext,msg);
  
      Int flag = msgsnd(msgid,(void*)&buf, sizeof(buf.mtext),0);
      if(flag<0){
          perror("msgsnd");
         return -4;
      }
      return 0;
  }
  int RecvMsgQueue(int msgid, int recvtype, char* out){
      struct msgbuf buf;
      ssize_t s = msgrcv(msgid,(void*)&buf, sizeof(buf.mtext), recvtype, 0);
      if(s<0){
      perror("msgvcv");
     return -5;
      }
  
      strcpy(out, buf.mtext);
      return s;
  }
  int DestroyMsgQueue(int msgid){
      int flag = msgctl(msgid, IPC_RMID, NULL);
      if(flag<0){
          perror("");
          return -3;
      }
      return 0;
 }


Client.c

 #include"commom.h"
   #include"commom.c"
  
int main(){
       int msgid = GetMsgQueue();
   
       char msg[1024];
       while(1){
       int r = RecvMsgQueue(msgid, SERVE,msg);
      if(r<0){
      perror("recv wrong");
      return -3;
      }
      printf("serve say:%s\n", msg);
  
      printf("please write: ");
      fflush(stdout);
      ssize_t s=read(0, msg, sizeof(msg)-1);
      if(s<0){
          perror("fread");
          return -1;
      }
      msg[s-1] = 0;
  
      int k = SendMsgQueue(msgid, CLIENT, msg);
      if(k<0){
      perror("send wrongs");
      return -2;
      }
      }
     
      return 0;
  }

Serves.c

   #include"commom.h"
   #include"commom.c"
 
 int main(){
       umask(0);
       int msgid = CreatMsgQueue();
   
       char msg[1024];
       while(1){
      printf("please write: ");
      fflush(stdout);
      ssize_t s=read(0, msg, sizeof(msg)-1);
      if(s<0){
          perror("fread");
          return -1;
      }
      msg[s-1] = 0;
  
      int k = SendMsgQueue(msgid, SERVE, msg);
      if(k<0){
      perror("send wrongs");
      return -2;
      }
      int r = RecvMsgQueue(msgid, CLIENT,msg);
      if(r<0){
      perror("recv wrong");
      return -3;
      }
      printf("client say:%s\n", msg);
      }
      
      DestroyMsgQueue(msgid);
      return 0;
  }


Makefile

.PHONY:all
   all:client serve
   
   client:client.c  commom.h
      gcc -o [email protected] $^
   serve:serves.c  commom.h
       gcc -o [email protected] $^
   
  .PHONY:clean
  clean:
      rm -f client serve

執行介面(先執行serve再執行client)

 

 

分享如上,如有錯誤望指標,共同學習!

相關推薦

程序通行IPC--實現訊息佇列驗證

今天我們來分享一下程序通行(IPC)-實現訊息佇列。 訊息佇列由作業系統提供一個連結串列(也就是說訊息佇列需要作業系統介面),以連結串列節點為一個數據塊(有型別),基於訊息,每條訊息有上限且訊息的總數

【Linux】程序間通訊IPC訊息佇列詳解測試用例

學習環境 Centos6.5 Linux 核心 2.6 什麼是訊息佇列? 訊息佇列是SystemV版本中三種程序通訊機制之一,另外兩種是訊號量和共享儲存段。訊息佇列提供了程序間傳送資料塊的方法,而且每個資料塊都有一個型別標識。訊息佇列是基於訊息的,而管

Android使用AIDL實現程序通訊IPC

前言:在還沒有做任何一件事情之前,千萬不要覺得這件事情很難,因為還沒有開始做內心就已經對這件事情產生了恐懼,這將會阻止你的進步,也許當你動手開始做了這件事後發現其實並不是很難。 一、 AIDL概述 含義:AIDL(Android Interface Defi

Android開發之AIDL實現遠端服務程序通訊IPC

首先什麼是AIDL呢,它是Android系統中的一種介面定義語言,用於約束兩個程序間的通訊規則,供編譯器生成程式碼。 實現Android裝置上的兩個程序間通訊(IPC),程序之間的通訊資訊首先會被轉換成AIDL協議資訊,然後傳送給對方;對方接收到AIDL協議資

程序間通訊筆記3—POSIX訊息佇列

POSIX 訊息佇列 1.概述 訊息佇列可認為是一個訊息連結串列,頭訊息指定當前佇列的兩個屬性:佇列中允許的最大訊息數和每個訊息的最大大小。而每個訊息本身除了資料之外還包括優先順序和資料長度等內容。 1.1POSIX訊息佇列和SystemV訊息佇列的區

Spark Streaming實時流處理筆記4—— 分散式訊息佇列Kafka

1 Kafka概述 和訊息系統類似 1.1 訊息中介軟體 生產者和消費者 1.2 Kafka 架構和概念 producer:生產者(生產饅頭) consumer:消費者(吃饅頭) broker:籃子 topic : 主題,給饅頭帶一個標籤,(

RabbitMQ訊息佇列-服務詳細配置與日常監控管理

RabbitMQ服務管理 啟動服務:rabbitmq-server -detached【 /usr/local/rabbitmq/sbin/rabbitmq-server -detached 】 檢視狀態:rabbitmqctl status 關閉服務:rabbitmqctl stop

RabbitMQ訊息佇列-高可用叢集部署實戰

前幾章講到RabbitMQ單主機模式的搭建和使用,我們在實際生產環境中出於對效能還有可用性的考慮會採用叢集的模式來部署RabbitMQ。 RabbitMQ叢集基本概念 Rabbit模式大概分為以下三種:單主機模式、普通叢集模式、映象叢集模式。 單主機模式:

RabbitMQ訊息佇列-通過Headers模式分發訊息

Headers型別的exchange使用的比較少,以至於官方文件貌似都沒提到,它是忽略routingKey的一種路由方式。是使用Headers來匹配的。Headers是一個鍵值對,可以定義成Hashtable。傳送者在傳送的時候定義一些鍵值對,接收者也可以再繫結時候傳入一些鍵值對,兩者匹配的

RabbitMQ訊息佇列-通過Topic主題模式分發訊息

前兩章我們講了RabbitMQ的direct模式和fanout模式,本章介紹topic主題模式的應用。如果對direct模式下通過routingkey來匹配訊息的模式已經有一定了解那fanout也很好理解。簡單的可以理解成direct是通過routingkey精準匹配的,而topic是通過r

RabbitMQ訊息佇列-通過fanout模式將訊息推送到多個Queue中

前面第六章我們使用的是direct直連模式來進行訊息投遞和分發。本章將介紹如何使用fanout模式將訊息推送到多個佇列。 有時我們會遇到這樣的情況,多個功能模組都希望得到完整的訊息資料。例如一個log的訊息,一個我們希望輸出在螢幕上實時監控,另外一個使用者持久化日誌。這時就可以使用fano

RabbitMQ訊息佇列-訊息任務分發與訊息ACK確認機制PHP版

在前面一章介紹了在PHP中如何使用RabbitMQ,至此入門的的部分就完成了,我們內心中一定還有很多疑問:如果多個消費者消費同一個佇列怎麼辦?如果這幾個消費者分任務的權重不同怎麼辦?怎麼把同一個佇列不同級別的任務分發給不同的消費者?如果消費者異常離線怎麼辦?不要著急,後面將慢慢解開面紗。我們

RabbitMQ訊息佇列-安裝amqp擴充套件並訂閱/釋出DemoPHP版

本文將介紹在PHP中如何使用RabbitMQ來實現訊息的訂閱和釋出。我使用的系統依然是Centos7,為了方便,應用伺服器我使用Docker進行部署,容器環境:centos7+nginx+php5.6。 執行環境,安裝AMQP擴充套件: 如何安裝Docker我就不說了,網上很多教程非

十三RabbitMQ訊息佇列-VirtualHost與許可權管理

VirtualHost 像mysql有資料庫的概念並且可以指定使用者對庫和表等操作的許可權。那RabbitMQ呢?RabbitMQ也有類似的許可權管理。在RabbitMQ中可以虛擬訊息伺服器VirtualHost,每個VirtualHost相當月一個相對獨立的RabbitMQ伺服器,每個

kafka01——分散式訊息佇列kafka概述

kafka是什麼? Apache Kafka是一個開源訊息系統,由Scala寫成。是由Apache軟體基金會開發的一個開源訊息系統專案。 Kafka最初是由LinkedIn開發,並於2011年初開源。 該專案的目標是為處理實時資料提供一個統一、高通量、低等待的

Java架構之訊息佇列 訊息佇列的概述

訊息佇列系列分享大綱:  一、訊息佇列的概述 二、訊息佇列之RabbitMQ的使用 三、訊息佇列之Kafka的使用 四、訊息佇列之RabbitMQ的原理詳解 五、訊息佇列之Kafka的原理詳解 六、訊息佇列之面試集錦 1.訊息佇列的概述 訊息佇列(Me

C++ 多執行緒框架3訊息佇列

之前,多執行緒一些基本的東西,包括執行緒建立,互斥鎖,訊號量,我們都已經封裝,下面來看看訊息佇列 我們儘量少用系統自帶的訊息佇列(比如Linux的sys/msgqueue),那樣移植性不是很強,我們希望的訊息佇列,在訊息打包和提取都是用的標準的C++資料結構,當然,

訊息佇列】MSMQ——微軟訊息佇列簡介安裝

一、前言       從這篇部落格開始小編就從一個簡單的例項來展示一下訊息佇列中MSMQ的基本使用方法,展示一下他對訊息的增刪改查,訊息佇列有很多種樣式,做.NET開發的程式猿,最容易安裝的就是MSM

RabbitMQ訊息佇列-RabbitMQ訊息佇列架構與基本概念

沒錯我還是沒有講怎麼安裝和寫一個HelloWord,不過快了,這一章我們先了解下RabbitMQ的基本概念。 RabbitMQ架構 說是架構其實更像是應用場景下的架構(自己畫的有點醜,勿嫌棄) 從圖中可以看出RabbitMQ主要由Exchange和Qu

微信小程序小結4 -- 分包加載程序間跳轉

項目 devel 目前 圖片 ria 首頁 .com logs path 分包加載 某些情況下,開發者需要將小程序劃分成不同的子包,在構建時打包成不同的分包,用戶在使用時按需進行加載(主要是空間不夠用,哈哈~)。 在構建小程序分包項目時,構建會輸出一個或多個功能的分包,其中