嵌入式學習筆記--Linux系統編程階段--DAY07進程間通信--存儲映射和共享內存

1.存儲映射

存儲映射 I/O (Memory-mapped I/O) 使一個磁盤文件存儲空間中的一個緩沖區相映射。于是當從緩沖區中取數據,就相當于讀文件中的相應字節。于此類似,將數據存入緩沖區則相應的字節就自動寫入文件。這樣,就可在不適用 read 和 write 函數的情況下,使用地址(指針)完成 I/O 操作。 使用存儲映射這種方法,首先應通知內核,將一個指定文件映射到存儲區域中。這個映射工作可以通過mmap 函數來實現。
? ? ?這個文件僅僅是用來進程間通信的橋梁。

1.1mmap函數映射

mmap函數:建立映射區

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
參數解釋
addr 地址,填 NULL(讓系統自己找一個合理的地址
length 長度 要申請的映射區的長度
prot 權限(讀還是寫)
????????PROT_READ 可讀
????????PROT_WRITE 可寫
flags 標志位
????????MAP_SHARED 共享的 -- 對映射區的修改會影響源文件(一般是這個)
????????MAP_PRIVATE 私有的
fd 文件描述符 需要打開一個文件
offset 指定一個偏移位置 ,從該位置開始映射(一般寫0,不偏移)
返回值
????????成功 返回映射區的首地址
????????失敗 返回 MAP_FAILED ((void *) -1)

1.2munmap函數

munmap函數:解除映射(斷開當前進程和磁盤文件的映射關系,不影響其他進程的映射)

int munmap(void *addr, size_t length);
參數解釋
????????addr 映射區的首地址
????????length 映射區的長度
返回值
????????成功 返回 0
????????失敗 返回 -1

1.3truncate函數

truncate函數:拓展文件的大小
一般磁盤映射是新建一個文件,這個文件新建的時候,大小是0,因此里面無法存儲數據,所以需要拓展文件的大小
int truncate(const char *path, off_t length);
參數解釋
????????path 要拓展的文件
????????length 要拓展的長度

1.4代碼案例

不相關的進程間通信

寫代碼:

#define _POSIX_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<string.h>
#include <sys/mman.h>int main(int argc, char const *argv[])
{//1.通過open打開文件int fd = open("temp",O_RDWR |O_CREAT,0666);//新建的文件無大小//2.拓展文件的大小truncate("temp",16);//3.建立映射char *buff = (char *)mmap(NULL,16,PROT_READ | PROT_WRITE,MAP_SHARED ,fd,0);//4.使用內存區域strcpy(buff,"hello mmap");//5.斷開映射munmap(buff,16);close(fd);return 0;
}

讀代碼:

#define _POSIX_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>int main(int argc, char const *argv[])
{//1.通過open打開文件int fd = open("temp",O_RDWR |O_CREAT,0666);//新建的文件無大小//2.拓展文件的大小truncate("temp",16);//3.建立映射char *buff = (char *)mmap(NULL,16,PROT_READ | PROT_WRITE,MAP_SHARED ,fd,0);//4.使用內存區域printf("收到數據%s\n",buff);printf("收到數據%s\n",buff);//5.斷開映射munmap(buff,16);close(fd);return 0;
}

除非被覆蓋,否則數據一直在

2.共享內存

2.1共享內存理論

共享內存允許兩個或者多個進程共享給定的存儲區域。(進程間通信的最快的方式)

共享內存的特點

1、 共享內存是進程間共享數據的一種最快的方法。 一個進程向共享的內存區域寫入了數據, 共享這個內存區域的所有進程就可以立刻看到其中的內容。

2、 使用共享內存要注意的是多個進程之間對一個給定存儲區訪問的互斥若一個進程正在向共享內存區寫數據, 則在它做完這一步操作前, 別的進程不應當去讀、 寫這些數據

在 ubuntu 部分版本中共享內存限制值如下 共享存儲區的最小字節數:

1 共享存儲區的最大字節數: 32M

共享存儲區的最大個數: 4096

每個進程最多能映射的共享存儲區的個數: 4096

2.2共享內存的API

shmget函數:創建或打開一塊共享內存區,即獲得一個共享內存標識符

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size,int shmflg);
功能:
????????創建或打開一塊共享內存區
參數:
????????key:IPC 鍵值(需要ftok函數)
????????size:該共享存儲段的長度(字節)
????????shmflg:標識函數的行為及共享內存的權限。
????????????????參數:shmflg:
????????????????????????IPC_CREAT:如果不存在就創建
????????????????????????IPC_EXCL:如果已經存在則返回失敗
????????????????????????位或權限位:共享內存位或權限位后可以設置共享內存的訪問權限,格式 和 open 函數的 mode_t 一樣,但可執行權限未使用
返回值:
????????成功:返回共享內存標識符。
????????失敗:返回-1

使用 shell 命令操作共享內存

查看共享內存

ipcs -m --內存

ipcs -q --隊列

ipcrm -m shmid --刪除shmid的共享內存

代碼案例:

創建一個共享內存,獲取標識符:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{ // 1.獲取唯一key值key_t key = ftok("/home/qf/桌面", 2504);// 2.得到唯一共享內存標識(分配物理內存)int shm_id = shmget(key,16,IPC_CREAT | 0666) ;  printf("%d\n",shm_id);return 0;
}

shmat函數:將一個共享內存段映射到調用進程的數據段中,即建立進程與物理內存的映射

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr,int shmflg);
函數功能:
????????將一個共享內存段映射到調用進程的數據段中。
參數:
????????shmid:共享內存標識符。
????????shmaddr:共享內存映射地址(若為 NULL 則由系 統自動指 定),推薦使用 NULL
????????shmflg:共享內存段的訪問權限和映射條件(映射時的讀寫關系)
????????????????0:共享內存具有可讀可寫權限。
????????????????SHM_RDONLY:只讀。
????????????????SHM_RND:(shmaddr 非空時才有效)(自己申請的虛擬地址來進行映射(例如malloc來的),建議shmaddr選NUMM)
????????????????沒有指定 SHM_RND 則此段連接到 shmaddr 所指定的地址上(shmaddr 必需 頁對齊)。 指定了 SHM_RND 則此段連接到 shmaddr- shmaddr%SHMLBA 所表示的地址 上。
返回值:
成功:返回共享內存段映射地址
失敗:返回 -1
代碼案例:建立內存與進程間的映射
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{ // 1.獲取唯一key值key_t key = ftok("/home/qf/桌面", 2504);// 2.得到唯一共享內存標識(分配物理內存)int shm_id = shmget(key,16,IPC_CREAT | 0666) ;  printf("%d\n",shm_id);//3.建立進程和物理內存間的映射char *p = (char *)shmat(shm_id,NULL,0);//4.斷開映射,只斷開自己return 0;
}

shmdt函數:將共享內存和當前進程分離(僅僅是斷開聯系并不刪除共享內存)

#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
功能:
????????將共享內存和當前進程分離(僅僅是斷開聯系并不刪除共享內存)
參數:
????????shmaddr:共享內存映射地址。
返回值:
成功返回 0
失敗返回 -1

shmctl:共享內存控制函數

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd,struct shmid_ds *buf);
功能:
????????共享內存空間的控制。
參數:
????????shmid:共享內存標識符。
????????cmd:函數功能的控制。
????????buf:shmid_ds 數據類型的地址,用來存放或修改共享內存的屬性。
????????????????cmd:函數功能的控制
????????????????????????IPC_RMID:刪除。
????????????????????????IPC_SET:設置 shmid_ds 參數。
????????????????????????IPC_STAT:保存 shmid_ds 參數。
????????????????????????SHM_LOCK:鎖定共享內存段(超級用戶)
????????????????????????SHM_UNLOCK:解鎖共享內存段。
返回值:
成功返回 0
失敗返回 -1
注意:
SHM_LOCK 用于鎖定內存,禁止內存交換。并不代表共享內存被鎖定后,禁止其它進程訪問。其真正的意義是:被鎖定的內存不允許被交換到虛擬內存中(即只針對當前進程)。這樣做的優勢在于讓共享內存一直處于內存中,從而提高程序性能

讀寫代碼案例:

寫:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{ // 1.獲取唯一key值key_t key = ftok("/home/qf/桌面", 2504);// 2.得到唯一共享內存標識(分配物理內存)int shm_id = shmget(key,16,IPC_CREAT | 0666) ;  printf("%d\n",shm_id);//3.建立進程和物理內存間的映射char *p = (char *)shmat(shm_id,NULL,0);strcpy(p,"hello world!");//4.斷開映射,只斷開自己shmdt(p);return 0;
}

讀:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main(int argc, char const *argv[])
{ // 1.獲取唯一key值key_t key = ftok("/home/qf/桌面", 2504);// 2.得到唯一共享內存標識(分配物理內存)int shm_id = shmget(key,16,IPC_CREAT | 0666) ;  printf("%d\n",shm_id);//3.建立進程和物理內存間的映射char *p = (char *)shmat(shm_id,NULL,SHM_RDONLY);printf("收到數據:%s\n",p);//4.斷開映射,只斷開自己return 0;
}

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

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

相關文章

.Net程序員就業現狀以及學習路線圖(四)

一、.Net程序員就業現狀分析 1. 市場需求與崗位分布 2025年數據顯示&#xff0c;.Net開發崗位在全國IT崗位中占比約0.009%&#xff0c;主要集中在一線城市如深圳、上海等地 2 4。行業分布呈現以下特點&#xff1a;?軟件行業?&#xff1a;占比43.3% ?研發領域?&#xff1a;占…

Monorepo 是什么?如何使用并寫自己的第三方庫

1. 什么是 Monorepo&#xff1f; Monorepo&#xff08;單倉庫&#xff09;指的是把多個項目/包放在一個代碼倉庫里統一管理。常見結構&#xff1a; /repo-root/packages/ui-lib/utils/apps/web-apppackage.jsonpnpm-workspace.yaml好處&#xff1a; 內部庫能直接共享&#xff0…

使用CI/CD部署后端項目(gin)

寫在前面&#xff1a;使用CI/CD部署gin項目到服務器中 前端可以參考&#xff1a;使用CI/CD部署nextjs項目 使用 GitHub Actions 配置后端 CI/CD&#xff08;含部署到服務器&#xff09; 本文檔介紹如何在 GitHub 倉庫中配置 CI/CD&#xff0c;將 PROJECT_NAME 項目自動構建并…

Coze添加知識庫解析的Embedding和PaddleOCR模型配置

1. Embedding模型配置 使用ollama模型&#xff0c;導入qwen3的embedding-8B模型&#xff0c;導入流程參考&#xff1a; Ollama離線部署模型 qwen3-Embedding模型文件可從魔塔社區下載&#xff1a; Qwen3-Embedding-8B 1.2 Coze配置 在coze_studio/docker目錄下輸入: vim .en…

02-Media-6-rtsp_server.py 使用RTSP服務器流式傳輸H264和H265編碼視頻和音頻的示例程序

rtsp_server.py 是使用k230的板載攝像頭和WIFI聯網功能,使用RTSP服務器流式傳輸視頻和音頻的程序示例。程序核心是創建了一個RtspServer類,該類用于初始化、啟動、停止RTSP服務器,并進行視頻和音頻的流傳輸。 一、首先,程序導入必要的模塊,包括視頻編碼、傳感器、媒體處理…

13-Java-面向對象-封裝和this關鍵字

文章目錄封裝this關鍵字封裝 告訴我們&#xff0c;如何正確設計對象的屬性和方法。原則&#xff1a;對象代表什么&#xff0c;就得封裝對應的數據&#xff0c;并提供數據對應的行為 package common;/*** Author: 大海* Date: 2025-09-06*/public class GirlFriend {/*private…

三高項目-緩存設計

三高項目-緩存設計 分流、并發 導流&#xff1a;將原本復雜操作的請求&#xff0c;引導到簡單的操作上。以后再來查&#xff0c;不需要經過復雜的計算。 成本&#xff1a;空間&#xff0c;收益&#xff1a;節省了時間。 不要以為僅僅是 redis&#xff0c;map等。 對應。kv…

happen-before原則

什么是 happen-before 原則&#xff1f; happen-before 是一個邏輯關系&#xff0c;用于描述兩個操作之間的 “先后順序”—— 如果操作 A happen-before 操作 B&#xff0c;那么 A 的執行結果必須對 B 可見&#xff0c;且 A 的執行順序在邏輯上先于 B。也就是保證指令有序性和…

4.1 機器學習 - 評估指標

模型評估是判斷 “模型是否有效” 的核心環節&#xff0c;需結合任務類型&#xff08;分類 / 回歸&#xff09;、數據分布&#xff08;如類別不平衡&#xff09;和商業目標選擇指標。本節聚焦分類任務的核心評估指標&#xff0c;從定義、計算邏輯到適用場景逐一拆解&#xff0c…

雅菲奧朗SRE知識墻分享(七):『可觀測性的定義與實踐』

在分布式系統日益復雜的當下&#xff0c;故障不再是“是否發生”&#xff0c;而是“何時爆發”。SRE可觀測性正是應對不確定性的“顯微鏡”與“導航儀”&#xff1a;通過指標、日志、追蹤三大數據血脈&#xff0c;實時外化系統黑盒&#xff0c;讓每一次抖動、每一行報錯、每一次…

C++ 詳細講解vector類

目錄 1. 什么是vector? 2. vector的使用 1. 構造函數---初始化 1. 默認構造函數(無參構造&#xff09; 2. 填充構造函數(指定數量和初始值&#xff09; 3. 范圍構造函數(通過迭代器拷貝其他容器元素&#xff09; 4. 拷貝構造函數(直接拷貝另一個vector&#xff09; 注…

Windows Server2012 R2 安裝.NET Framework 3.5

Windows Server2012 R2 安裝.NET Framework 3.5 虛擬機系統是Windowsserver 2012R2&#xff0c;在安裝SQlserver2012時候警告未安裝.NET Framework 3.5。于是找了個.NET Framework 3.5的安裝包&#xff0c;但是由于系統原因無法正常安裝。按照提示從控制面板-程序-啟動或關閉Wi…

IDEA中Transaction翻譯插件無法使用,重新配置Transaction插件方法

原因 由于Transaction默認的翻譯引擎為谷歌翻譯&#xff0c;由于一些原因&#xff0c;這個翻譯無法使用&#xff0c;因此導致插件無法使用。 解決辦法 更換Transaction插件翻譯引擎即可。 方法步驟 1.進入Idea的設置里&#xff0c;找到Tool下的Transaction選項2.更改翻譯引擎&a…

外置flash提示音打包腳本

批處理腳本說明文檔 - 音頻資源打包與分發 一、腳本功能概述 本批處理腳本&#xff08;.bat 文件&#xff09;用于將指定目錄下的多個音頻文件&#xff08;.wtg 和 .mp3 格式&#xff09;打包為音頻資源配置文件&#xff08;tone.cfg&#xff09;&#xff0c;進一步將配置文件與…

Go語言設計模式(三)抽象工廠模式

抽象工廠模式與工廠模式類似,被認為是工廠方法模式的另一層抽象.抽象工廠模式圍繞創建其他工廠的超級工廠工作.1.角色:1.1抽象產品:構成產品系列的一組不同但相關的產品的聲明接口.1.2具體產品:實現抽象產品接口的類,主要用于定義產品對象,由相應的具體工廠創建.1.3抽象工廠:創…

大狗王 DG1+ 13.6G礦機詳細參數解析與性能評測

近年來&#xff0c;隨著加密貨幣挖礦行業的不斷發展&#xff0c;越來越多的礦機廠商推出了高性能、低功耗的礦機設備。大狗王&#xff08;DG1&#xff09;13.6G礦機便是其中一款備受關注的設備&#xff0c;特別是在LTC&#xff08;萊特幣&#xff09;、Doge&#xff08;狗狗幣&…

Python 算術運算練習題

計算數字特征值題目描述 編寫一個程序&#xff0c;接收用戶輸入的兩個整數 a 和 b&#xff08;a > b > 0&#xff09;&#xff0c;計算并輸出以下結果&#xff1a;a 與 b 的和的平方a 除以 b 的商和余數a 與 b 的平均數&#xff08;保留 2 位小數&#xff09;示例請輸入整…

OS項目構建效能改進策劃方案

一、現狀分析與問題定位構建穩定性問題&#xff1a; 表現&#xff1a;非代碼變更引發的構建失敗&#xff08;如環境依賴、工具鏈版本、第三方庫更新、資源競爭等&#xff09;“幽靈構建”時有發生。影響&#xff1a;嚴重破壞開發流程的順暢性&#xff0c;耗費大量開發/測試人員…

Ai8051 2.4寸320*240 ILI9341 I8080接口驅動

/*---------------------------------------------------------------------*/ /* --- Web: www.STCAI.com ---------------------------------------------*/ /* 液晶屏驅動程序參考wiki技術網站提供的開源源碼&#xff0c;僅供學習使用 */ /*----------------------…

最大似然估計:損失函數的底層數學原理

引言當你第一次看到線性回歸時&#xff0c;你是否注意到了作為參數優化關鍵的損失函數&#xff08;均方損失&#xff09;&#xff0c;你是否能夠理解它的本質和由來。其實&#xff0c;在我第一次接觸時&#xff0c;我是感到有些驚訝的&#xff0c;然后試著去強行理解它&#xf…