linux 進程間通信_共享內存

目錄

一、什么是共享內存?

二、共享內存的特點

優點

缺點

三、使用共享內存的基本函數

?1、創建共享內存shmget()

2、掛接共享內存shmat

3、脫離掛接shmdt

?4、共享內存控制shmctl

?5.查看和刪除共享內存

comm.hpp

server.cc?

Client.cc?

Makefile


一、什么是共享內存?

共享內存(Shared Memory)是一種高效的?進程間通信(IPC)機制?,允許多個進程直接訪問同一塊物理內存區域,實現數據的快速交換。它是IPC中速度最快的方式,因為共享內存方式的通信沒有中間過程,而管道、消息隊列等方式則需要將數據通過中間機制進行轉換。

?共享內存的原理如上圖所示,主要分為兩部(創內存、掛接)

1.進程在物理內存上開辟一塊空間,這塊空間稱為共享內存。

2.不同進程將這塊空間掛接到自己的進程地址空間中。

3.進程通過虛擬地址和頁表的映射找到共享內存,然后對共享內存進行讀寫數據。

二、共享內存的特點

優點

  1. ?高效性?:共享內存是所有進程間通信方式中速度最快的,因為所有進程共享同一塊內存,訪問共享內存區域和訪問進程獨有的內存區域一樣快,并不需要通過系統調用或者其它需要切入內核的過程來完成。
  2. ?直接訪問?:避免了數據的各種不必要的復制,數據直接寫到內存,不用若干次數據拷貝。
  3. ?靈活性?:不像匿名管道那樣要求通信的進程有一定的父子關系。

缺點

  1. ?缺乏同步機制?:系統內核沒有對訪問共享內存進行同步,必須提供自己的同步措施。例如,在數據被寫入之前不允許進程從共享內存中讀取信息、不允許兩個進程同時向同一個共享內存地址寫入數據等。
  2. ?生命周期?:共享內存的生命周期隨內核,即如果用戶不使用系統調用釋放它,直到操作系統關機之前它會一直存在。
  3. ?管理復雜性?:需要額外的同步機制(如信號量、互斥鎖)保證數據一致性。

三、使用共享內存的基本函數

?1、創建共享內存shmget()

 int shmget(key_t key, size_t size, int shmflg);
參數key:這個共享內存段名字(和消息隊列一樣由ftok獲取)size:共享內存??(自己指定,一般為頁的整數倍)shmflg:由九個權限標志構成,它們的?法和創建?件時使?的mode模式標志是?樣的IPC_CREAT:創建新的共享內存IPC_CREAT|IPC_EXCL|0666:若創建的共享內存存在,報錯IPC_NOWAIT:非阻塞0:如果是打開文件,寫0
返回值:成功返回?個?負整數,即該共享內存段的標識碼;失敗返回-1

2、掛接共享內存shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);
參數shmid: 共享內存標識shmaddr:指定連接的地址(一般默認為NULL,由系統自動分配內存)shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY(連接操作用于只讀內存)
返回值:成功返回?個指針,指向共享內存第?個節;失敗返回-1

3、脫離掛接shmdt

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

?4、共享內存控制shmctl

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
參數shmid:由shmget返回的共享內存標識碼cmd:將要采取的動作(有三個可取值)buf:指向?個保存著共享內存的模式狀態和訪問權限的數據結構
返回值:成功返回0;失敗返回-1

?5.查看和刪除共享內存

//查看
ipcs -m
//刪除
ipcrm -m id(標識)

共享內存使用案例:

分為兩個進程,客戶端(Client)和服務端(server)?

前提介紹:

.hpp文件的作用與.h文件功能類似

.cc文件等于.cpp文件

comm.hpp

#include <iostream>
#include<stdio.h>
#include <string>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include<string.h>const std::string gpath = "/root/day5_24";
const int gid = 0x6666;
const int gshmsize = 4096;
const int gmode = 0600;
class ShareMemory
{
public:ShareMemory() : _shmid(-1), _ret(nullptr){}~ShareMemory(){}// 創建共享內存int CreateShm(){key_t key = ::ftok(gpath.c_str(), gid);if (key < 0){printf("ftok error\n");return 1;}_shmid = ::shmget(key, gshmsize, IPC_CREAT | IPC_EXCL | gmode);if (_shmid < 0){printf("shmget error\n");return 2;}return _shmid;}// 獲得共享內存void GetShm(){key_t key = ::ftok(gpath.c_str(), gid);if (key < 0){printf("ftok error\n");}_shmid = ::shmget(key, gshmsize, IPC_CREAT|gmode);std::cout << "_shmid: " << _shmid << std::endl;if (_shmid < 0){printf("shmget error\n");}}// 掛地址void AttachShm(){_ret = shmat(_shmid, nullptr, 0);std::cout <<  "_shmid: " << _shmid << std::endl;}// 去關聯void DetachShm(){int d = shmdt(_ret);if (d == -1){printf("shmdt error\n");return;}printf("shmdt success\n");}// 釋放內存void DeleteShm(){shmctl(_shmid, IPC_RMID, nullptr);}void *getadder(){return _ret;}void ShmMeta(){//}private:int _shmid;void *_ret;
};ShareMemory sm;

server.cc?

#include"time.hpp"
#include "Comm.hpp"
using namespace std;int main()
{sm.CreateShm();sm.AttachShm();// 在此處讀出while(true){char* image=(char*)sm.getadder();std::cout << image << std::endl;sleep(1);}sm.DetachShm();sm.DeleteShm();return 0;
}

Client.cc?

#include "Comm.hpp"
#include"time.hpp"
int main()
{sm.GetShm();sm.AttachShm();// 在此處寫入char*image = (char*)sm.getadder();char i[] = "i am processA";while (true){strcpy(image, i);sleep(1);}sm.DetachShm();return 0;
}

Makefile

SERVER=server
CLIENT=client
CC=g++
SERVER_SRC=Server.cc
Client_SRC=Client.cc.PHONY:all
all:$(SERVER) $(CLIENT)$(SERVER):$(SERVER_SRC)$(CC) -o $@ $^ -std=c++11 -g
$(CLIENT):$(Client_SRC)$(CC) -o $@ $^ -std=c++11 -g.PHONY:clean
clean:rm -f $(SERVER) $(CLIENT)

----------------------------------------------------------------------------------------------------------------------------

本篇介紹到此結束,有問題歡迎給我評論留言。謝謝

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

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

相關文章

Spring Boot 登錄實現:JWT 與 Session 全面對比與實戰講解

Spring Boot 登錄實現&#xff1a;JWT 與 Session 全面對比與實戰講解 2025.5.21-23:11今天在學習黑馬點評時突然發現用的是與蒼穹外賣jwt不一樣的登錄方式-Session&#xff0c;于是就想記錄一下這兩種方式有什么不同 在實際開發中&#xff0c;登錄認證是后端最基礎也是最重要…

Vue中的 VueComponent

VueComponent 組件的本質 Vue 組件是一個可復用的 Vue 實例。每個組件本質上就是通過 Vue.extend() 創建的構造函數&#xff0c;或者在 Vue 3 中是由函數式 API&#xff08;Composition API&#xff09;創建的。 // Vue 2 const MyComponent Vue.extend({template: <div…

使用 FFmpeg 將視頻轉換為高質量 GIF(保留原始尺寸和幀率)

在制作教程動圖、產品展示、前端 UI 演示等場景中,我們經常需要將視頻轉換為體積合適且清晰的 GIF 動圖。本文將詳細介紹如何使用 FFmpeg 工具將視頻轉為高質量 GIF,包括: ? 保留原視頻尺寸或自定義縮放? 保留原始幀率或自定義幀率? 使用調色板優化色彩質量? 降低體積同…

【自然語言處理與大模型】大模型Agent四大的組件

大模型Agent是基于大型語言模型構建的智能體&#xff0c;它們能夠模擬獨立思考過程&#xff0c;靈活調用各類工具&#xff0c;逐步達成預設目標。這類智能體的設計旨在通過感知、思考與行動三者的緊密結合來完成復雜任務。下面將從大模型大腦&#xff08;LLM&#xff09;、規劃…

《軟件工程》第 11 章 - 結構化軟件開發

結構化軟件開發是一種傳統且經典的軟件開發方法&#xff0c;它強調將軟件系統分解為多個獨立的模塊&#xff0c;通過數據流和控制流來描述系統的行為。本章將結合 Java 代碼示例、可視化圖表&#xff0c;深入講解面向數據流的分析與設計方法以及實時系統設計的相關內容。 11.1 …

初步嘗試AI應用開發平臺——Dify的本地部署和應用開發

隨著大語言模型LLM和相關應用的流行&#xff0c;在本地部署并構建知識庫&#xff0c;結合企業的行業經驗或個人的知識積累進行定制化開發&#xff0c;是LLM的一個重點發展方向&#xff0c;在此方向上也涌現出了眾多軟件框架和工具集&#xff0c;Dify就是其中廣受關注的一款&…

高階數據結構——哈希表的實現

目錄 1.概念引入 2.哈希的概念&#xff1a; 2.1 什么叫映射&#xff1f; 2.2 直接定址法 2.3 哈希沖突&#xff08;哈希碰撞&#xff09; 2.4 負載因子 2.5 哈希函數 2.5.1 除法散列法&#xff08;除留余數法&#xff09; 2.5.2 乘法散列法&#xff08;了解&#xff09…

7.安卓逆向2-frida hook技術-介紹

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a;圖靈Python學院 工具下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取碼&#xff1…

DB-GPT擴展自定義Agent配置說明

簡介 文章主要介紹了如何擴展一個自定義Agent&#xff0c;這里是用官方提供的總結摘要的Agent做了個示例&#xff0c;先給大家看下顯示效果 代碼目錄 博主將代碼放在core目錄了&#xff0c;后續經過對源碼的解讀感覺放在dbgpt_serve.agent.agents.expand目錄下可能更合適&…

Android 架構演進之路:從 MVC 到 MVI,擁抱單向數據流的革命

在移動應用開發的世界里&#xff0c;架構模式的演進從未停歇。從早期的 MVC 到后來的 MVP、MVVM&#xff0c;每一次變革都在嘗試解決前一代架構的痛點。而今天&#xff0c;我們將探討一種全新的架構模式 ——MVI&#xff08;Model-View-Intent&#xff09;&#xff0c;它借鑒了…

【YOLOv8-pose部署至RK3588】模型訓練→轉換RKNN→開發板部署

已在GitHub開源與本博客同步的YOLOv8_RK3588_object_pose 項目&#xff0c;地址&#xff1a;https://github.com/A7bert777/YOLOv8_RK3588_object_pose 詳細使用教程&#xff0c;可參考README.md或參考本博客第六章 模型部署 文章目錄 一、項目回顧二、文件梳理三、YOLOv8-pose…

集成30+辦公功能的實用工具

軟件介紹 本文介紹的軟件是千峰辦公助手。 軟件功能概述與開發目的 千峰辦公助手集成了自動任務、系統工具、文件工具、PDF工具、OCR圖文識別、文字處理、電子表格七個模塊&#xff0c;擁有30余項實用功能。作者開發該軟件的目的是解決常見辦公痛點&#xff0c;把機械操作交…

IDEA啟動報錯:Cannot invoke “org.flowable.common.engine.impl.persistence.ent

1.問題 項目啟動報錯信息 java.lang.NullPointerException: Cannot invoke "org.flowable.common.engine.impl.persistence.ent 2.問題解析 出現這個問題是在項目中集成了Flowable或Activiti工作流&#xff0c;開啟自動創建工作流創建的表&#xff0c;因為不同環境的數據…

網絡安全--PHP第三天

今天學習文件上傳的相關知識 上傳的前端頁面如下 upload.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

【愚公系列】《生產線數字化設計與仿真》004-顏色分類站仿真(基礎概念)

??【技術大咖愚公搬代碼:全棧專家的成長之路,你關注的寶藏博主在這里!】?? ??開發者圈持續輸出高質量干貨的"愚公精神"踐行者——全網百萬開發者都在追更的頂級技術博主! ?? 江湖人稱"愚公搬代碼",用七年如一日的精神深耕技術領域,以"…

基于 uni-app + <movable-view>拖拽實現的標簽排序-適用于微信小程序、H5等多端

在實際業務中&#xff0c;我們經常遇到「標簽排序」或「菜單調整」的場景。微信小程序原生的 movable-view 為我們提供了一個簡單、高效的拖拽能力&#xff0c;結合 Vue3 uni-app 的組合&#xff0c;我們可以實現一個體驗良好的標簽管理界面。 核心組件&#xff1a;<movab…

一些較好的學習方法

1、網上有一些非常經典的電路&#xff0c;而且有很多視頻博主做了詳細的講解。 2、有一部分拆解的UP主&#xff0c;拆解后會還原該器件的原理圖&#xff0c;并一步步做講解。 3、有兩本書&#xff0c;數電、模電&#xff0c;這兩本書中的內容很多都值得學習。 5、某寶上賣的…

《1.1_4計算機網絡的分類|精講篇|附X-mind思維導圖》

網絡相關知識 按使用范圍分類 公用網 由電信部門或其他提供通信服務的經營部門組建、管理和控制&#xff0c;向全社會提供服務的網絡。 專用網 由某個單位或部門組建、僅供本單位或部門內部使用的網絡。 按傳輸介質分類 有線網絡 如&#xff1a;雙絞線、同軸電纜、光纖…

Git 和 GitHub 學習指南本地 Git 配置、基礎命令、GitHub 上傳流程、企業開發中 Git 的使用流程、以及如何將代碼部署到生產服務器

Windows 上 Git 安裝與配置 下載安裝&#xff1a;訪問 Git 官方網站下載適用于 Windows 的安裝程序。運行安裝包時會出現許可協議、安裝目錄、組件選擇等界面&#xff08;如下圖&#xff09;。在“Select Components”頁面建議勾選 Git Bash Here 等選項&#xff0c;以便在資源…

航空航天領域對滾珠絲桿的精度要求有多高?

航空航天領域對滾珠絲桿的精度要求非常高&#xff0c;尤其是飛行器、火箭和衛星等載具的導航和定位系統都需要高精度的滾珠絲桿&#xff0c;以確保高精度的位置控制和穩定的導航性能。那么&#xff0c;航空航天領域對滾珠絲桿的精度要求有多高&#xff1f; 1、定位精度&#xf…