Linux進程通信——共享內存

概念

共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。

特點

共享內存是最快的一種 IPC,因為進程是直接對內存進行存取
因為多個進程可以同時操作,所以需要進行同步
信號量+共享內存通常結合在一起使用,信號量用來同步對共享內存的訪問。

原理

創建

1、創建共享內存
2、進程A連接共享內存,寫入數據(這里需要給進程A一個睡眠時間:兩個進程同時操作需要同步,進程A寫入數據后睡眠一定時間,在這個時間內進程B將數據讀取,實現數據交換)
3、進程A斷開連接
4、進程B連接共享內存,讀取數據
5、進程B斷開連接
6、釋放公共內存

常用API

頭文件

#include <sys/types.h>
#include <sys/shm.h>
//以下幾個API都包含以上兩個頭文件

shmget函數

功能

創建或獲取一個共享內存

函數原型

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

參數解讀

keyftok生成的key標識,標識系統的唯一IPC資源
size需要申請共享內存的大小。在操作系統中,申請內存的最小單位為頁,一頁是4k字節,為了避免內存碎片,我們一般申請的內存大小為頁的整數倍,即以兆為單位
shmflg如果要創建新的共享內存,需要使用IPC_CREAT,IPC_EXCL,后面需要加權限標志,權限標志與文件的讀取操作一樣。如果是已經存在的,可以使用IPC_CREAT或直接傳0(只需獲取而不用創建,yi)

返回值

成功時返回一個新建或已經存在的的共享內存標識符,取決于shmflg的參數。失敗返回-1并設置錯誤碼。

shmat函數

功能

第一次創建完共享內存時,它還不能被任何進程訪問,shmat函數的作用就是用來啟動對該共享內存的訪問,并把共享內存連接到當前進程的地址空間,即將共享內存映射進進程中。

函數原型

void *shmat(int shm_id, const void *shm_addr, int shmflg); 

參數解讀

shm_id由shmget函數返回的共享內存標識
*shm_addr指定共享內存連接到當前進程中的地址位置,通常為空(為0),表示讓系統為我們安排共享內存的地址
shmflg

若指定了SHM RDONLY位,則以只讀方式連接此段,否則以讀寫方式連接此段(輸入0即可,表示映射進的共享內存可讀可寫

返回值

成功返回共享存段的指針(虛擬地址),并且內核將使其與該共享存段相關的shmid_ds(第四個函數的第三個參數)結構中的shm_nattch計數器加1 (類似于引用計數,即內存占用計入總內存) ; 出錯返回-1

shmdt函數

功能

當一個進程不需要共享內存的時候,就需要去關聯。該函數并不刪除所指定的共享內存區,而是將之前用shmat函數連接好的共享內存區脫離目前的進程

函數原型

int shmdt(const void *shmaddr);?

參數解讀

*shmaddr:是shmat函數返回的地址指針,只需將其返回值的函數變量名(代碼地址)寫入即可

返回值

調用成功時返回0,失敗時返回-1。

shmctl函數

功能

控制共享內存

函數原型

int shmctl(int shm_id, int command, struct shmid_ds *buf);  

參數解讀

shm_idshmget函數返回的共享內存標識符
commandcommand是要采取的操作,它可以取下面的三個值
IPC_STAT把shmid_ds結構中的數據設置為共享內存的當前關聯值,即用共享內存的當前關聯值覆蓋shmid_ds的值
IPC_SET如果進程有足夠的權限,就把共享內存的當前關聯值設置為shmid_ds結構中給出的值
IPC_RMID(常用)刪除共享內存段

*bufbuf是一個結構指針,它指向共享內存模式和訪問權限的結構(不關心,一般寫0

返回值

成功時返回0,失敗返回-1并設置錯誤碼。

代碼示例

shmw.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>int main()
{key_t key;int shmid;char *shmaddr = NULL;	key = ftok(".",1);//當前目錄建立IPCshmid = shmget(key,1024*4,IPC_CREAT|0666);//以可讀可寫方式開辟一個4兆大小的共享內存if(shmid == -1){printf("create gxdl failed\n");exit(-1);}shmaddr = shmat(shmid,0,0);//將共享內存映射到進程中printf("connect success!\n");strcpy(shmaddr,"hello word!");sleep(5);//因為寫入和讀取是同步,所以此時執行完寫入代碼后需等待讀取數據后一起關閉共享內存shmdt(shmaddr);//斷開連接共享內存shmctl(shmid,IPC_RMID,0);//刪除共享內存printf("over\n");return 0;
}

shmr.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>int main()
{key_t key;int shmid;char *shmaddr = NULL;	key = ftok(".",1);shmid = shmget(key,1024*4,0);//這里只需找到已經開辟的共享內存,所以參數為0即可if(shmid == -1){printf("create gxdl failed\n");exit(-1);}shmaddr = shmat(shmid,0,0);//映射共享內存printf("connect success!\n");printf("content is %s\n",shmaddr);//將共享內存數據打印出來shmdt(shmaddr);//斷開共享內存printf("over\n");return 0;
}

shmw.c程序運行,寫入端往共享內存寫入數據,并讓其等待5s,這5s內shmr.c程序運行,讀取端讀取共享內存數據并將內容打印出來,5s后兩者同時關閉共享內存輸出over。

fork函數的補充

功能

系統IPC鍵值的格式轉換函數,系統建立IPC通訊 (消息隊列、信號量和共享內存) 時必須指定一個ID值。通常情況下,該id值通過ftok函數得到。

函數原型

key_t ftok( const char * fname, int id );

參數解讀

fname就是你指定的文件名(已經存在的文件名),一般使用當前目錄
id子序號。雖然是int類型,但是只使用8bits(1-255)

例如

key_t key;
key = ftok(".", 1); //當前文件只需加.

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

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

相關文章

Open3D (C++) 計算兩點云之間的最小距離

目錄 一、 算法原理二、代碼實現三、結果展示本文由CSDN點云俠原創,原文鏈接。如果你不是在點云俠的博客中看到該文章,那么此處便是不要臉的爬蟲與GPT。 一、 算法原理 Open3D中ComputePointCloudDistance函數提供了計算從源點云到目標點云的距離的方法,計算點云的距離。也…

python數據結構與算法-05_棧

棧 棧這個詞實際上在計算機科學里使用很多&#xff0c;除了數據結構外&#xff0c;還有內存里的棧區 &#xff08;和堆對應&#xff09;&#xff0c;熟悉 C 系語言的話應該不會陌生。 上一章我們講到了先進先出 queue&#xff0c;其實用 python 的內置類型 collections.deque …

【C語法學習】26 - strcmp()函數

文章目錄 1 函數原型2 參數3 返回值4 比較機制5 示例5.1 示例1 1 函數原型 strcmp()&#xff1a;比較str1指向的字符串和str2指向的字符串&#xff0c;函數原型如下&#xff1a; int strcmp(const char *str1, const char *str2);2 參數 strcmp()函數有兩個參數str1和str2&a…

HCIP-四、MUX-vlanSuper-vlan+端口安全

四、MUX-vlan&Super-vlan端口安全 MUX-vlan實驗拓撲實驗需求及解法1. 在SW1/2/3分別創建vlan10 20 30 402. SW1/2/3之間使用trunk鏈路&#xff0c;僅允許vlan10 20 30 40 通過。3. SW與PC/Server之間使用access鏈路。4. ping驗證&#xff1a; Super-vlan端口安全實驗拓撲實…

【騰訊云云上實驗室-向量數據庫】騰訊云開創新時代,發布全新向量數據庫Tencent Cloud VectorDB

前言 隨著人工智能、數據挖掘等技術的飛速發展&#xff0c;海量數據的存儲和分析越來越成為重要的研究方向。在海量數據中找到具有相似性或相關性的數據對于實現精準推薦、搜索等應用至關重要。傳統關系型數據庫存在一些缺陷&#xff0c;例如存儲效率低、查詢耗時長等問題&…

CentOS使用docker安裝OpenGauss數據庫

1.搜索OpenGauss docker search opengauss 2.選擇其中一個源拉取 docker pull docker.io/enmotech/opengauss 3.運行OpenGauss docker run --name opengauss --privilegedtrue --restartalways -d -e GS_USERNAMEpostgres -e GS_PASSWORDmyGauss2023 -p 5432:5432 docker.…

黑馬React18: ReactRouter

黑馬React: ReactRouter Date: November 21, 2023 Sum: React路由基礎、路由導航、導航傳參、嵌套路由配置 路由快速上手 1. 什么是前端路由 一個路徑 path 對應一個組件 component 當我們在瀏覽器中訪問一個 path 的時候&#xff0c;path 對應的組件會在頁面中進行渲染 2. …

2023年中國高壓驅動芯片分類、市場規模及發展趨勢分析[圖]

高壓驅動芯片是一種能在高壓環境下工作的集成電路&#xff0c;主要用于控制和驅動各種功率器件&#xff0c;如繼電器、電磁閥、電機、變頻器等。高壓驅動芯片根據其輸出電流的大小和形式可分為兩類恒流型和開關型。 高壓驅動芯片分類 資料來源&#xff1a;共研產業咨詢&#x…

藍橋杯算法雙周賽心得——迷宮逃脫(記憶化搜索)

大家好&#xff0c;我是晴天學長&#xff0c;非常經典實用的記憶化搜索題&#xff0c;當然也可以用dp做&#xff0c;我也會發dp的題解&#xff0c;需要的小伙伴可以關注支持一下哦&#xff01;后續會繼續更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .迷宮逃脫 迷官逃脫…

ubuntu操作系統中docker下Hadoop分布式前置環境配置實驗

版本&#xff1a; centos7 hadoop 3.1.3 java JDK:1.8 集群規劃&#xff1a; masterslave1slave2HDFS NameNode DataNode DataNode SecondryNameNode DataNode YARNNodeManager ResourceManage NodeManager NodeManager 1.docker容器&#xff1a; 把普通用戶加入到docker組&am…

opencv-Canny 邊緣檢測

Canny邊緣檢測是一種經典的圖像邊緣檢測算法&#xff0c;它在圖像中找到強度梯度的變化&#xff0c;從而識別出圖像中的邊緣。Canny邊緣檢測的優點包括高靈敏度和低誤檢率。 在OpenCV中&#xff0c;cv2.Canny() 函數用于執行Canny邊緣檢測。 基本語法如下&#xff1a; edges…

代碼隨想錄 134. 加油站

題目 在一條環路上有 n 個加油站&#xff0c;其中第 i 個加油站有汽油 gas[i] 升。 你有一輛油箱容量無限的的汽車&#xff0c;從第 i 個加油站開往第 i1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發&#xff0c;開始時油箱為空。 給定兩個整數數組 gas 和 cos…

本地訓練,開箱可用,Bert-VITS2 V2.0.2版本本地基于現有數據集訓練(原神刻晴)

按照固有思維方式&#xff0c;深度學習的訓練環節應該在云端&#xff0c;畢竟本地硬件條件有限。但事實上&#xff0c;在語音識別和自然語言處理層面&#xff0c;即使相對較少的數據量也可以訓練出高性能的模型&#xff0c;對于預算有限的同學們來說&#xff0c;也沒必要花冤枉…

阿里云 ACK 新升級,打造智算時代的現代化應用平臺

云布道師 今天&#xff0c;能想到的或是想不到的領域&#xff0c;對容器和 Kubernetes 的需求都居高不減&#xff0c;使這項技術正在真正走向無處不在。 在 2023 云棲大會上&#xff0c;阿里云云原生產品線容器服務負責人易立關于容器服務 ACK 在本屆亞運會上應用的介紹&#…

[crash] cxa_pure_virtual 崩潰分析與原理

摘要&#xff1a;工作過程中處理線上的崩潰時發現了一例cxa_pure_virtual相關的crash&#xff0c;直接看堆棧基本山很容易確認是有異步調用導致出發了ABI的異常。但是對于為什么會觸發cxa_pure_virtual雖然有大致的猜測但是沒有直接的證據&#xff0c;因此本文主要描述觸發該類…

C/C++未定義行為的例子匯總

一、什么是未定義行為&#xff1f; 未定義行為&#xff08;Undefined Behavior&#xff09;是指C語言標準未做規定的行為。同時&#xff0c;標準也從沒要求編譯器判斷未定義行為&#xff0c;所以這些行為有編譯器自行處理&#xff0c;在不同的編譯器可能會產生不同的結果&#…

ElasticSearch之cat aliases API

執行aliases命令&#xff0c;如下&#xff1a; curl -X GET "https://localhost:9200/_cat/aliases?pretty&vtrue" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下&#xff1a; alias index …

在 VSCode 中使用 GDB 進行 C/C++ 程序調試(圖文版)

(??? )&#xff0c;Hello我是祐言QAQ我的博客主頁&#xff1a;C/C語言&#xff0c;數據結構&#xff0c;Linux基礎&#xff0c;ARM開發板&#xff0c;網絡編程等領域UP&#x1f30d;快上&#x1f698;&#xff0c;一起學習&#xff0c;讓我們成為一個強大的攻城獅&#xff0…

webpack loader

1、分類 2、執行順序 配置類型 執行順序是 loader1>loader2>loader3 3、使用方式 自己的第一個loader 同步loader /*** loader 就是一個函數* 當webpack 解釋資源時&#xff0c; 會調用相應的loader去處理* loader 接收到文件內容作為參數&#xff0c;返回文件內容* p…

Nginx 開源版安裝

下載 tar.gz安裝包&#xff0c;上傳。 解壓 [rootlocalhost ~]# tar zxvf nginx-1.21.6.tar.gz nginx-1.21.6/ nginx-1.21.6/auto/ nginx-1.21.6/conf/ nginx-1.21.6/contrib/ nginx-1.21.6/src/ ... ...安裝gcc [rootlocalhost nginx-1.21.6]# yum install -y gcc 已加載插件…