Linux——共享內存

目錄

一、共享內存概念

?二、共享內存的一些函數

2.1 shmget 創建共享內存

2.2 shmat 訪問共享內存?

2.3?shmdt 解除共享內存的映射

2.4?shnctl 刪除共享內存段

三、共享內存?

3.1 創建測試進程

3.2 使用循環測試

?編輯

3.3?共享內存寫入程序

3.4 帶有信號量的共享內存?


一、共享內存概念

共享內存是一種進程間通信的方式,允許多個進程訪問和操作同一塊內存區域。這樣的內存區域被所有共享它的進程所擁有,進程可以將數據寫入共享內存區域,也可以從中讀取數據。共享內存在提高進程通信效率和降低開銷方面具有優勢,但也需要進行同步和互斥操作以避免數據競爭和沖突。

共享內存通常適用于需要高效地在進程間傳遞大量數據的場景,比如多個進程需要共享大型數據結構、圖形圖像處理或多媒體應用等。在使用共享內存時,需要注意管理內存的權限、同步訪問和處理異常情況等問題,以確保數據的一致性和安全性。

?二、共享內存的一些函數

2.1 shmget 創建共享內存

它的函數原型如下:

int shmget(key_t key, size_t size, int shmflg);

參數含義:

1. key: 用于標識共享內存段的鍵值,不同的進程使用相同的 key 值可以獲取到同一個共享內存
2. size: 創建共享內存時,指定要申請的共享內存空間大小
3. shmflg:?用于指定創建共享內存段的訪問權限和其他標志,比如權限位和內存段的創建方式等。常見的標志包括IPC_CREAT(如果不存在則創建共享內存段)和?IPC_EXCL(如果存在則返回錯誤)。
shmget() 成功則返回共享內存的 ID, 失敗返回-1
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}}

2.2 shmat 訪問共享內存?

函數shmat()用于將共享內存段附加到調用進程的地址空間,并返回一個指向共享內存段起始地址的指針。

它的函數原型如下:

void* shmat(int shmid, const void *shmaddr, int shmflg);

參數含義:

  1. shmid: 表示要附加的共享內存段的標識符,通常是由shmget()函數返回的共享內存標識符。

  2. shmaddr: 指定共享內存段連接到調用進程地址空間的地址。一般設置為?NULL,由系統自動選擇映射的虛擬地址空間

  3. shmflg: 用以指定附加共享內存段的附加方式。常見的標志包括SHM_RDONLY(只讀方式附加共享內存段)和?SHM_RND(指示共享內存段將在系統限定的地址范圍內附加)。?一般給 0, 可以給 SHM_RDONLY 為只讀模式,其他的為讀寫

返回值:

? ? ? ?函數的返回值是一個指針,指向共享內存段的起始地址。 ?shmat()成功則返回共享內存的首地址,失敗返回 NULL
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}strcpy(s,"hello");shmdt(s);}

2.3?shmdt 解除共享內存的映射

當進程不再需要訪問共享內存時,需要使用?shmdt?函數將共享內存段從進程地址空間中解除映射。其函數原型如下:

int shmdt(const void *shmaddr);
參數含義:
  1. shmaddr: 表示要分離的共享內存段的起始地址。通常是由shmat()函數返回的指針,指向共享內存段的起始位置。

返回值:

????????當成功分離共享內存段時,函數返回0。如果出現錯誤,函數會返回-1,并且可以通過檢查errno變量來獲取錯誤信息。

2.4?shnctl 刪除共享內存段

函數shmctl()用于控制共享內存段的屬性

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

參數含義:

  1. shmid: 共享內存段的標識符,通常由shmget()函數返回。

  2. cmd: 控制命令,指定對共享內存段執行的操作類型。常見的命令有:

    • IPC_STAT: 獲取共享內存段的狀態信息,并將其存儲在buf指向的shmid_ds結構體中。
    • IPC_SET: 設置共享內存段的權限模式,需要提供buf指向的shmid_ds結構體。
    • IPC_RMID: 從系統中刪除共享內存段,同時釋放其占用的資源。
  3. buf: 指向一個shmid_ds結構體的指針,用于存儲或傳遞共享內存段的狀態信息或權限設置。

返回值:

????????函數成功執行時返回0,否則返回-1,并通過設置errno變量來指示錯誤類型。

三、共享內存?

3.1 創建測試進程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}printf("s=%s\n",s);// 打印共享內存的地址shmdt(s);}

運行結果:

3.2 使用循環測試

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}while(1){if(strncmp(s,"end",3) == 0){break;}printf("s=%s\n",s);sleep(1);}shmdt(s);}

3.3?共享內存寫入程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}while(1){printf("input\n");char buff[128]={0};fgets(buff,128,stdin);strcpy(s,buff);if( strncmp(buff,"end",3) == 0){break;}}shmdt(s);
}

3.4 帶有信號量的共享內存?

首先要創建兩個信號量,一個設為0,另一個設為1。

頭文件代碼sem.h

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/sem.h>enum INDEX{SEM1=0,SEM2};union semun
{int val;
};void sem_init();//創建并初始化信號量
void sem_p(int index);
void sem_v(int index);
void sem_destroy();

sem.c代碼

#include"sem.h"static int semid=-1;void sem_init()//創建并初始化信號量
{semid=semget((key_t)1234,2,IPC_CREAT|IPC_EXCL|0600);if(semid==-1){semid=semget((key_t)1234,2,0600);if(semid==-1){printf("semget err\n");}}else{int arr[2]={1,0};for(int i=0;i<2;i++){union semun a;a.val=arr[i];if(semctl(semid,i,SETVAL,a)==-1){printf("semctl init err\n");}}}
}void sem_p(int index)
{struct sembuf buf;buf.sem_num=index;buf.sem_op=-1;//pbuf.sem_flg=SEM_UNDO;if(semop(semid,&buf,1) == -1){printf("op p err\n");}
}void sem_v(int index)
{struct sembuf buf;buf.sem_num=index;buf.sem_op=1;//vbuf.sem_flg=SEM_UNDO;if(semop(semid,&buf,1) == -1){printf("op v err\n");}
}void sem_destroy()
{if(semctl(semid,0,IPC_RMID) == -1){printf("semctl del\n");}
}

使用信號量的main.c代碼

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
#include"sem.h"int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}sem_init();//創建 初始化while(1){printf("input\n");char buff[128]={0};fgets(buff,128,stdin);sem_p(SEM1);//p  s1strcpy(s,buff);sem_v(SEM2);//v  s2if( strncmp(buff,"end",3) == 0){break;}}shmdt(s);
}

測試代碼test.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
#include"sem.h"int main()
{int shmid = shmget((key_t)2345,128,IPC_CREAT|0600);if(shmid == -1){exit(1);}char* s=(char*)shmat(shmid,NULL,0);if(s==(char*)-1){exit(1);}sem_init();while(1){sem_p(SEM2);if(strncmp(s,"end",3) == 0){break;}printf("s=%s\n",s);sem_v(SEM1);}shmdt(s);sem_destroy();exit(0);
}

運行結果:

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

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

相關文章

數啟新疆,智領未來!2025新疆數字經濟發展戰略研討會在烏市啟幕

2025年4月20日&#xff0c;由新疆維吾爾自治區數字經濟聯合會主辦、中鈞科技有限公司承辦的"2025新疆數字經濟發展戰略研討會"將在烏魯木齊水磨溝區金正大廈三層會議中心隆重召開。 作為本年度新疆數字經濟領域規格最高的行業盛會&#xff0c;會議將匯聚自治區14個廳…

Nginx:輕量級高性能的Web服務器與反向代理服務器

目錄 一.引言 二.Nginx的核心特點 2.1高性能與高并發 2.2低資源消耗 2.3功能豐富 2.4高度擴展性 三.Nginx的應用場景 3.1靜態資源服務器 3.2反向代理服務器 3.3API網關 3.4Nginx的配置與使用 四.總結 一.引言 在互聯網高速發展的今天&#xff0c;Web服務器的性能與…

嵌入式Linux設備使用Go語言快速構建Web服務,實現設備參數配置管理方案探究

本文探討&#xff0c;利用Go語言及gin框架在嵌入式Linux設備上高效搭建Web服務器&#xff0c;以實現設備參數的網頁配置。通過gin框架&#xff0c;我們可以在幾分鐘內創建一個功能完善的管理界面&#xff0c;方便對諸如集中器&#xff0c;集線器等沒有界面的嵌入式設備的管理。…

KALI搭建log4j2靶場及漏洞復現全流程

這里使用了兩臺KALI虛擬機&#xff0c;一臺用于安裝靶場環境&#xff0c;一臺用于攻擊 一、Docker的安裝&#xff08;靶機&#xff09; 1、Linux內核版本查看 #安裝docker要求內核版本kerner>3.10 #為此&#xff0c;先檢查當前Linux系統的內核版本 uname -a 2、Linux apt…

學習筆記—C++—模板初階

目錄 模板初階 泛型編程 函數模板 模版概念 函數模版格式 模版的原理 函數模板的實例化 模版參數的匹配規則 類模板 模板初階 泛型編程 使用函數重載雖然可以實現&#xff0c;但是有一下幾個不好的地方&#xff1a; 1. 重載的函數僅僅是類型不同&#xff0c;代碼復…

Docker 中多個容器之間的通信

在 Docker 中&#xff0c;多個容器之間的通信可以通過以下幾種主要方式實現&#xff0c;具體選擇取決于網絡需求、隔離性及管理復雜度&#xff1a; 一、自定義 Bridge 網絡&#xff08;推薦&#xff09; 通過創建自定義的 Docker 網絡&#xff0c;容器可以加入同一網絡并通過容…

Day1-初次接觸UFS

經過導師初次介紹&#xff0c;了解工作以芯片測試為主&#xff0c;需堅持學習&#xff0c;小白大致需3-6月入門。整體學習應分為3大塊&#xff0c;UFS協議占40%&#xff08;3-4h&#xff09;,C技能占40%&#xff08;3-4h&#xff09;,工具或業務占20%&#xff08;1-2h&#xff…

【LeetCode 熱題100】二叉樹構造題精講:前序 + 中序建樹 有序數組構造 BST(力扣105 / 108)(Go語言版)

&#x1f331; 二叉樹構造題精講&#xff1a;前序 中序建樹 & 有序數組構造 BST 本文圍繞二叉樹的兩類構造類題目展開解析&#xff1a; 從前序與中序遍歷序列構造二叉樹 將有序數組轉換為二叉搜索樹 我們將從「已知遍歷構造樹」和「平衡構造 BST」兩個角度&#xff0c;拆…

JMeter重要的是什么

重要特性 支持多種協議&#xff1a; JMeter支持對多種協議進行性能測試&#xff0c;包括HTTP、HTTPS、FTP、JDBC&#xff08;數據庫&#xff09;、LDAP、JMS、SOAP、REST等。這使得它能夠適應各種不同的測試場景。強大的負載模擬能力&#xff1a; JMeter能夠模擬大量的虛擬用戶…

一文讀懂WPF系列之MVVM

WPF MVVM 什么是MVVMWPF為何使用MVVM機制WPFMVVM 的實現手段 INotifyPropertyChanged?數據綁定的源端通知??原理 PropertyChanged事件雙向綁定的完整條件常見疑惑問題 什么是MVVM 翻譯全稱就是 model-view-viewmodel 3部分內容 以wpf的概念角度來解釋就是 數據庫數據源模型…

OCR API識別對比

OCR 識別DEMO OCR識別 demo 文檔由來 最開始想使用百度開源的 paddlepaddle大模型 研究了幾天&#xff0c;發現表格識別會跨行&#xff0c;手寫識別的也不很準確。最終還是得使用現成提供的api。。 文檔說明 三個體驗下來 騰訊的識別度比較高&#xff0c;不論是手寫還是識別表…

嵌入式MCU常用模塊

日后填坑。 無線通信模塊 2.4G 基本介紹 以NRF24L01為例。 NRF24L01是一款2.4GHz的無線收發模塊&#xff0c;支持SPI通信協議&#xff0c;具有低功耗、高數據速率&#xff08;250kbps-2Mbps&#xff09;和多設備通信能力。 它可以同時與最多6個其他模塊通信&#xff0c;適合…

記一次InternVL3- 2B 8B的部署測驗日志

測試效果&#xff1a; 問題和耗時如圖 5、資源占用 不釋放資源會一直漲顯存。總體還算滿意&#xff0c;我試了好多個圖理解大模型&#xff0c;就屬它牛一點 附圖一張 補充&#xff0c;測試InternVL3-2B的結果 1、模型下載魔搭社區 2、運行環境&#xff1a; 1、硬件 RTX 30…

Java版本對應關系表

Java版本對應關系表 以下Java主要版本&#xff08;Major Version&#xff09;與公開大版本號的對應關系 公開大版本名稱Major 版本號內部版本號格式示例&#xff08;java -version輸出&#xff09;Java 8 (1.8)52 (0x34)1.8.0_XXX1.8.0_301Java 953 (0x35)9.0.X9.0.4Java 105…

2025最新版flink2.0.0安裝教程(保姆級)

Flink支持多種安裝模式。 local&#xff08;本地&#xff09;——本地模式 standalone——獨立模式&#xff0c;Flink自帶集群&#xff0c;開發測試環境使用 standaloneHA—獨立集群高可用模式&#xff0c;Flink自帶集群&#xff0c;開發測試環境使用 yarn——計算資源統一…

android11 配置默認電池優化白名單

目錄 1.介紹 2.讀取配置文件 3.默認配置一個白名單列表 1.介紹 在 Android 11 中,DeviceIdleController 是負責控制設備進入 Doze 模式(閑置模式) 的核心系統服務,其內部方法 readConfigFileLocked() 負責從配置文件中讀取 Doze 模式的行為參數,包括 idle 階段的時間間…

java中的Future的設計模式 手寫一個簡易的Future

案例 例如&#xff1a;今天是小妹的生日&#xff0c;需要一個蛋糕有點儀式感&#xff0c;于是去蛋糕店預定&#xff0c;預定完之后&#xff0c;店老板說蛋糕做好了&#xff0c;到時電話通知你&#xff0c;不可能在這傻傻的等著吧&#xff0c;還有其他事情要做啊&#xff0c;于…

【Redis】Redis C++使用

一、Redis的自定義網絡協議 1.1 為什么可以編寫出一個自定義的Redis客戶端 為什么我們可以編寫出一個自定義的Redis客戶端&#xff1f;因為Redis公開了自己的自定義協議。而對于一些其他軟件的客戶端&#xff0c;我們無法編寫出一個自定義的Redis客戶端&#xff0c;因為他們沒…

【軟考系統架構設計師】軟件工程知識點

1、 軟件開發生命周期 軟件定義時期&#xff1a;包括可行性研究和詳細需求分析過程&#xff0c;任務是確定軟件開發工程必須完成的總目標&#xff0c;具體分為問題定義、可行性研究、需求分析等 軟件開發時期&#xff1a;軟件的設計與實現&#xff0c;分為概要設計、詳細設計、…

DeepSeek 與開源:肥沃土壤孕育 AI 碩果

當國產 AI DeepSeek 以其低成本推理和多模態能力在全球范圍內引起轟動時&#xff0c;人們驚嘆于中國技術的迅猛發展&#xff0c;卻很少有人深究這一成就背后的根基。答案其實早已寫在中國開源生態二十多年的發展歷程中。 從倪光南院士提出“以開源打破技術壟斷”的理念&#x…