[linux]進程間通信(IPC)———共享內存(shm)(什么是共享內存,共享內存的原理圖,共享內存的接口,使用演示)

一、什么是共享內存

?共享內存區是最快的(進程間通信)IPC形式。一旦這樣的內存映射到共享它的進程的地址空間,這些進程間數據傳遞不再涉及到內核,換句話說是進程不再通過執行進入內核的系統調用來傳遞彼此的數據。注意:共享內存沒有進行同步與互斥!共享內存不會自動銷毀,要手動銷毀。

二、?共享內存的原理圖

三、共享內存的接口(什么用)

ftok

功能:生成一個key,key是shmget第一個參數,這個key是一個約定的數,讓不同的進程通過key找到同一份資源,不用再進入內存查找。

頭文件

#include <sys/types.h>
#include <sys/ipc.h>
原型
key_t ftok(const char *pathname, int proj_id);
參數

pathname:一個路徑字符串,可以隨便給

proj_id:一個int數據,可以隨便給

返回值:返回key

shmget

功能:用來創建共享內存

頭文件

#include <sys/ipc.h>
#include <sys/shm.h>
原型
int shmget(key_t key, size_t size, int shmflg);
參數
key:這個共享內存段名字,這個key是一個約定的數,讓不同的進程通過key找到同一份資源
size:共享內存的大小(一般取 n * 1024)
shmflg:由九個權限標志構成,它們的用法和創建文件時使用的mode模式標志是一樣的

主要用這兩個:

IPC_EXCL:不存在共享內存就創建,存在就使用現有的

IPC_EXCL:不存在共享內存就創建,存在就報錯,保證創建的共享內存是新的

返回值:成功返回一個非負整數,即該共享內存段的標識碼;失敗返回-1

shmat

功能:將共享內存段連接到進程地址空間

頭文件

?#include <sys/types.h>
?#include <sys/shm.h>

原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
參數
shmid: 共享內存標識,shmget的返回值
shmaddr:指定連接的地址
shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一個指針,指向共享內存第一個節;失敗返回-1

說明:
shmaddr為NULL,核心自動選擇一個地址
shmaddr不為NULL且shmflg無SHM_RND標記,則以shmaddr為連接地址。
shmaddr不為NULL且shmflg設置了SHM_RND標記,則連接的地址會自動向下調整為SHMLBA的整數倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示連接操作用來只讀共享內存

shmdt

功能:將共享內存段與當前進程脫離

頭文件

?#include <sys/types.h>
?#include <sys/shm.h>

原型
int shmdt(const void *shmaddr);
參數
shmaddr: 由shmat所返回的指針
返回值:成功返回0;失敗返回-1
注意:將共享內存段與當前進程脫離不等于刪除共享內存段,刪除共享內存用shmctl

shmctl

功能:用于控制共享內存

頭文件

?#include <sys/ipc.h>
?#include <sys/shm.h>
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
參數
shmid:由shmget返回的共享內存標識碼
cmd:將要采取的動作(有三個可取值)

  1. PC STAT 把shmid ds結構中的數據設置為共享內存的當前關聯值
  2. IPC SET 在進程有足夠權限的前提下,把共享內存的當前關聯值設置為shmid ds數據結構中給出的值
  3. IPC RMID 刪除共享內存段

buf:指向一個保存著共享內存的模式狀態和訪問權限的數據結構,一般設為nullptr
返回值:成功返回0;失敗返回-1

?四、使用演示

使用代碼創建一個共享內存, 支持兩個進程進行通信

?進程A 向共享內存當中寫 “i am process A”

?進程B 從共享內存當中讀出內容,并且打印到標準輸出

?使用到的linux的一些指令

ipcs -m:查看共享內存的消息

ipcrm -m shmid:刪除共享內存標識碼為shmid的共享內存

監視腳本

while :; do ipcs -m; sleep 1; done
功能:每隔一秒打印一次共享內存消息

shm.hpp

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string>
#include <cstring>
#include <iostream>
#include <unistd.h>using namespace std;const string pathname = "/home/lwj/code11";
const int proj_id = 0x112233;
const int size = 4096;
key_t Getkey()
{int key = ftok(pathname.c_str(), proj_id);if(key < 0){perror("ftok");exit(-1);}return key;
}char* gethex(int x)
{char s[1024];sprintf(s, "0x%x", x);return s;}

processA.cc

#include "shm.hpp"
int main()
{key_t key = Getkey();cout << "獲取key: " << gethex(key) << endl;sleep(10);//獲取shmidint shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0644);cout << "創建shm, 獲取shmid: " << shmid << endl; if(shmid < 0){cerr << "shmget fail" << endl;exit(-1);};sleep(10);//連接shmcout << "連接shm" << endl; char* s = (char*)shmat(shmid, nullptr, 0);sleep(10);//通信cout << "寫消息" << endl;string str = "i am process A";int i = 0;for (auto e : str){s[i] = e;i++;}s[i] = '\0';//斷開shmsleep(10);cout << "斷開shm" << endl; shmdt(s);sleep(10);//銷毀shmcout << "銷毀shm" << endl; shmctl(shmid, IPC_RMID, nullptr);return 0;
}

processB.cc

#include "shm.hpp"
int main()
{key_t key = Getkey();cout << "獲取key: " << gethex(key) << endl;sleep(5);// 獲取shmidint shmid = shmget(key, size, IPC_CREAT);cout << "創建shm, 獲取shmid: " << shmid << endl; if(shmid < 0){cerr << "shmget fail" << endl;exit(-1);}// 連接shmcout << "連接shm" << endl;char *s = (char *)shmat(shmid, nullptr, 0);sleep(5);// 通信cout << "讀消息: " << s << endl;// 斷開shmsleep(10);cout << "斷開shm" << endl;shmdt(s);sleep(10);// 銷毀shmcout << "銷毀shm" << endl;shmctl(shmid, IPC_RMID, nullptr);return 0;
}

Makefile

.PHNOY:all
all:processA processBprocessA:progressA.ccg++ -o $@ $^ -std=c++11
processB:progressB.ccg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f processA processB

演示效果視頻鏈接:

shm演示視頻-CSDN直播

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696072.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696072.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696072.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Three.js初學(2)

Three.js初學&#xff08;2&#xff09; 三維坐標系的認識1. 輔助坐標系 光源的影響1. 光材質的影響2. 光源介紹點光源環境光平行光 3. 光源衰減/位置 相機控件1. 引入擴展庫2. 使用方法 三維坐標系的認識 這一章節的主要作用是加強自我對三維坐標空間的認識。 1. 輔助坐標系…

貓頭虎分享已解決Bug || TypeError: Cannot set property ‘innerHTML‘ of null

博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的寶典&#xff01;《IDEA開發秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鴻蒙》 …

華為配置直連三層組網隧道轉發示例

配置直連三層組網隧道轉發示例 組網圖形 圖1 配置直連三層組網隧道轉發示例組網圖 業務需求組網需求數據規劃配置思路配置注意事項操作步驟配置文件擴展閱讀 業務需求 企業用戶接入WLAN網絡&#xff0c;以滿足移動辦公的最基本需求。且在覆蓋區域內移動發生漫游時&#xff0c;不…

Linux 系統編程:文件編程

本篇涉及文件的創建、打開、讀和關閉。 文件為操作系統服務和設備提供了一個簡單而一致的 接口 。“接口”指的是一種約定或標準&#xff0c;通過提供一個一致的接口&#xff0c;可以為上層隱藏底層硬件和服務的復雜性&#xff0c;上層無需關注它們的具體實現細節。 比如操作系…

Kafka進階

文章目錄 概要應用場景消息隊列兩種模式kafka的基礎架構分區常見問題小結 概要 kafka的傳統定義&#xff1a;kafka是一個分布式的基于發布\訂閱模式的消息隊列&#xff0c;主要用于大數據實時處理領域。 kafka的最新概念&#xff1a;kafka是一個開源的分布式事件流平臺&#x…

隨機森林模型、模型模擬技術和決策樹模型簡介

隨機森林模型、模型模擬技術和決策樹模型簡介 隨機森林模型 隨機森林模型是一種比較新的機器學習模型&#xff0c;它是通過集成學習的方法將多個決策樹模型組合起來&#xff0c;形成一個更加強大和穩定的模型。隨機森林模型的基本原理是“數據隨機”和“特征隨機”&#xff0…

10種常見的光伏發電量計算方法

光伏發電是一種將太陽能轉化為電能的清潔能源技術。隨著環境保護意識的日益增強和能源結構的轉型&#xff0c;光伏發電得到了廣泛的應用。對于光伏系統來說&#xff0c;發電量的準確計算是評估系統性能、預測長期收益和優化系統運行的關鍵。以下是常見的光伏發電量計算方法&…

Vista 2.08: The storm chaser

A story about Mathew —— the storm chaser. "He is too young to understand his dream and the Harvard is just others dream put into his mind." "You dont have to chase for the happiness that defined by others. You must define your own happines…

Python3零基礎教程之Python解釋器與開發環境搭建

大家好&#xff0c;我是千與編程&#xff0c;碩士畢業于北京大學&#xff0c;曾先后就職于字節跳動&#xff0c;京東等互聯網大廠&#xff0c;目前在編程導航知識星球擔任星球嘉賓&#xff0c;著有《AI算法畢設智囊袋》&#xff0c;《保姆級帶你通關秋招教程》兩大專欄。 今天開…

從it方面介紹部分好玩的電影

電影推薦 1.《黑客帝國》《The matrix》 僅推薦第一二三部2. 《代碼奔騰》《code rush》3 人物傳記類 《社交網絡》 《硅谷傳奇》 《喬布斯》4《模仿游戲》也是傳記 但主演是 卷福5 《環形使者》6 《蝴蝶效應》 三部7.《隱私大盜》8.《監視資本主義&#xff1a;智能陷阱》9. 劇…

RMAN備份與恢復

文章目錄 一、RMAN介紹二、全量備份三、增量備份0級備份1級增量備份累積性差量備份總結 四、壓縮備份壓縮備份介紹壓縮備份操作壓縮備份優缺點 五、異常恢復1、恢復前的準備2、恢復數據庫 六、RMAN相關參數 一、RMAN介紹 RMAN&#xff08;Recovery Manager&#xff09;是Oracl…

在做了frp的實驗室服務器不同端口間傳輸文件

背景 實驗室有兩臺服務器&#xff0c;使用的是一個IP&#xff0c;兩個端口&#xff0c;給人看上去是一臺服務器的兩個端口&#xff0c;實際是兩臺服務器。 現在我需要從一個端口傳輸一個文件夾到另外一個端口&#xff0c;實際上是從一個機器傳輸到另外一個機器。 操作 在兩臺…

linux系統消息中間件rabbitmq部署鏡像集群

RabbitMQ鏡像集群配置 RabbitMQ鏡像集群配置創建鏡像集群:鏡像隊列策略設置說明 RabbitMQ鏡像集群配置 上面已經完成RabbitMQ默認集群模式&#xff0c;但并不保證隊列的高可用性&#xff0c;盡管交換機、綁定這些可以復制到集群里的任何一個節點&#xff0c;但是隊列內容不會復…

thonny 使用命令行安裝包并且替換源,安裝速度嗖嗖的

thonny 使用命令行安裝包并且替換源 點擊 “工具”->"打開系統shell"替換源下載嘎嘎快 點擊 “工具”->“打開系統shell” 替換源 pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/ pip config set global.trusted-host mirrors.aliy…

AI Agent幾篇不錯的概述和介紹

?2023年人工智能體(AI Agent)開發與應用全面調研&#xff1a;概念、原理、開發、應用、挑戰、展望 OpenAI的CEO都在談的 AI Agent&#xff0c;到底是什么&#xff1f; | 人人都是產品經理 AI智能體卷爆大模型&#xff01;4大Agent打擂&#xff0c;西部世界誰將成為軟件2.0&am…

快速學習安全框架 Springsecurity最新版(6.2)--用戶授權模塊

簡介 上一節Springsecurity 用戶認證 Springsecurity 擁有強大的認證和授權功能并且非常靈活&#xff0c;,一來說我們都i有以下需求 可以幫助應用程序實現以下兩種常見的授權需求&#xff1a; 用戶-權限-資源&#xff1a;例如張三的權限是添加用戶、查看用戶列表&#xff0c;李…

康威生命游戲

康威生命游戲 康威生命游戲(Conway’s Game of Life)是康威發明的細胞自動機。 生命游戲有幾個簡單的規則&#xff1a; 細胞有兩種狀態&#xff0c;存活或死亡&#xff0c;每個細胞以自身為中心與周圍的八格細胞互動。 對于存活的細胞&#xff1a; 當周圍的細胞過少(<2)或…

【Linux】:簡易實現自動化構建代碼make/Makefile

朋友們、伙計們&#xff0c;我們又見面了&#xff0c;本期來給大家解讀一下有關Linux自動化構建代碼make/makefile的使用&#xff0c;如果看完之后對你有一定的啟發&#xff0c;那么請留下你的三連&#xff0c;祝大家心想事成&#xff01; C 語 言 專 欄&#xff1a;C語言&…

Leo贈書活動-18期 《高效使用Redis》

?作者簡介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;熱愛Java后端開發者&#xff0c;一個想要與大家共同進步的男人&#x1f609;&#x1f609; &#x1f34e;個人主頁&#xff1a;Leo的博客 &#x1f49e;當前專欄&#xff1a; 贈書活動專欄 ?特色專欄&#xff1a;…

Ubuntu22部署MySQL5.7詳細教程

Ubuntu22部署MySQL5.7詳細教程 一、下載MySQL安裝包二、安裝MySQL三、啟動MySQL檢查狀態登錄MySQL 四、開啟遠程訪問功能1、允許其他主機通過root訪問數據庫2、修改配置文件&#xff0c;允許其他IP通過自定義端口訪問 五、使用Navicat連接數據庫 默認情況下&#xff0c;Ubuntu2…