linux的通信方案(SYSTEM V)

文章目錄

      • 共享內存(Share Memory)
      • 信號隊列(Message Queue)
      • 信號量(semaphore)

進程間通信的核心理念:讓不同的進程看見同一塊資源
linux下的通信方案: SYSTEM V

共享內存(Share Memory)

特點:1.共享內存是進程見通信最最快的
?????????? 2.可以提供較大通信空間

注意:共享內存由于裸露給所有使用者,因此是需要維護的

做法:去申請一塊空間,讓其映射到對應的不同進程的進程地址空間。
如圖:
在這里插入圖片描述

那么具體是怎么做的呢?

  • linux是生成一個特定的key,有key作為表示這塊共享內存的唯一標識。
  • 不同進程在運行的時候憑借這個key拿到共享內存的shmid(類似于文件管理系統的fd),進行掛接到自己的進程地址空間上。
  • 申請的空間是不會自己釋放的,要么在程序里面用funtion控制,要么在外部手動釋放
  • ipcs -m

  • #查看當前有哪些共享內存

  • ipcrm -m shmid

  • #刪除對應的共享內存id

需要用到的系統調用:

shmget #創建共享內存
shmat # 掛接共享內存
shmdt # 取消掛接
shmctl # 操控這塊共享內存
unlink # 刪除文件

server:

#include "Common.hpp"class Init
{
public:Init(){bool r = MakeFifo();//用管道是為了進程進行時,具備一定順序性。if (!r)return;key_t key = GetKey();shmid = CreatShm(key);std::cout << "shmid:" << shmid << "\n";// sleep(5);std::cout << "開始將shm映射到進程地址空間\n";s = (char *)shmat(shmid, nullptr, 0);fd = open(filename.c_str(), O_RDONLY);}~Init(){close(fd);std::cout << "將shm從進程地址空間移除\n";shmdt(s);std::cout << "將共享內存從操作系統中釋放\n";shmctl(shmid, IPC_RMID, nullptr);unlink(filename.c_str());}int FileDirection(){return fd;}const char *ShnPtr(){return s;}private:int shmid;int fd;char *s;
};int main()
{Init init;// struct shmid_ds ds;// std::cout<<std::hex<<ds.shm_perm.__key<<"\n";// std::cout<<ds.shm_nattch<<"\n";while (true){int code = 0;ssize_t n = read(init.FileDirection(), &code, sizeof(code));if (n > 0){std::cout << "共享讀取:" << init.ShnPtr() << "\n";}else if (n == 0){break;}else{std::cerr << "讀取錯誤,錯誤碼:" << errno << "\n";}}return 0;
}

client

#include "Common.hpp"int main()
{key_t key = GetKey();int shmid = CreatShmHelper(key, IPC_CREAT | 0644);char *s = static_cast<char *>(shmat(shmid, nullptr, 0));std::cout << "attach shm done\n";int fd = open(filename.c_str(), O_WRONLY);for (int c = 0; c < 26; c++){s[c] = c + 'a';std::cout << "write:" << (char)c + 'a' << "done\n";sleep(1);int code = 1;write(fd, (char *)&code, sizeof(code));}// sleep(5);std::cout << "dettach shm done\n";shmdt(s);close(fd);return 0;
}

.h


#pragma once#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>const std::string pathname = "/home/fuh_cs/Desktop/cpp_learning/linux/ShareMemory/Common.hpp";
const int proj_id = 0x234;
const int size = 4096;
const std::string filename = "fifo";
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(-1);}return key;
}int CreatShmHelper(key_t key, int flag)
{int shmid = shmget(key, size, flag); //共享內存也有權限也是需要設置的// EXCL保證創建時如果存在就會失敗if (shmid < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(2);}return shmid;
}int CreatShm(key_t key)
{return shmget(key, size, IPC_CREAT | IPC_EXCL | 0644); //共享內存也有權限也是需要設置的
}int GetShm(key_t key)
{return shmget(key, size, IPC_CREAT); //共享內存也有權限也是需要設置的
}//為1創建成功
bool MakeFifo()
{int n = mkfifo(filename.c_str(), 0666);if (n < 0){std::cerr << "errno:" << errno << ",errstring" << strerror(errno) << std::endl;return 0;}std::cout << "mkfifo success..." << std::endl;return 1;
}

信號隊列(Message Queue)

基于SYSTEM V的還有對應的信號隊列(Message Queue),信號量
下面展示下Message Queue的簡單使用代碼。

基本的系統調用函數,在下面代碼中有,具體使用可以通過man手冊查詢。

#pragma once#include <iostream>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <sys/msg.h>
key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if (key < 0){std::cerr << "errno:" << errno << ",errnostring:" << std::strerror(errno) << std::endl;exit(-1);}return key;
}//消息隊列也是存在于內核之中,不手動關閉的生命周期和內核一起int main()
{key_t key = GetKey();int msgid =  msgget(key,IPC_CREAT |IPC_EXCL);std::cout<<"msgid:"<<msgid<<'\n';struct  msqid_ds ds;std::cout<<ds.__msg_cbytes<<'\n';std::cout<<ds.msg_perm.__key<<'\n';//用msgsend來發送消息//用msgrcv來接受消息msgctl(msgid,IPC_RMID,nullptr);//也可以  ipcrm -q msgid 在bash刪除return 0;}   

信號量(semaphore)

前置知識:

  • 公共資源:多個執行流看見的同一份資源
  • 多個執行流訪問同一份資源,就存在并發訪問
  • 為了解決并發訪問公共資源的問題,導致的數據不一致、臟讀等問題,需要保護資源
  • 因此引發出互斥和同步
  • 互斥:同一時刻,只能有一個執行流訪問資源,加鎖完成
  • 同步:多個執行流按照預定的先后次序來訪問公共資源
  • 被保護起來的資源,稱為臨界資源
  • 訪問臨界資源的執行流(或者代碼),稱為臨界區
    分析:
  • 本質是個計數器
  • 當進程需要訪問公共資源,先獲取信號量,再去訪問資源。(相當于信號量是獲取資源的憑證,有了信號量,就一定會有資源沒獲取信號量的進程,就阻塞等待
  • 信號量如果被獲取了,就沒了,沒被獲取,就全部都在。是只有兩種狀態,二元性的因此由此二元性,完成了互斥的功能
  • 不同的進程也需要看到同一份信號量,因此信號量也被納入IPC體系,也就是說,信號量由操作系統提供
  • 我們知道SYSTEM V的資源是可以看見的,但是信號量是原子的(atomic,不可在分的),即使被進程競爭的訪問,也只會出現要么獲取了,要么沒獲取信號量。不會出現獲取半個的情況。這種原子的獲取操作稱之為P操作。相對應原子的釋放,稱之為V操作。
    信號量系統調用

semget
semctl
semop

linux內核看SYSTEM V設計的共享內存等通信方式
一般來說:

  • 內核里面有一個ipc_id_ary,其是一個柔性數組,存儲了一個size表示大小和指針數組,size表示指針數組的個數
  • 這個指針數組所存的指針類型是 **kern_ipc_perm***的指針類型
  • 由SYSTEM V標準下設計出來的共享內存,信號隊列等,內核里面都是由一個自己類型的結構體去管理的(例如:msg_queue,就是管理信號隊列的結構體,Shmid_Kernel, 就是管理共享內存的結構體)
  • 而這些結構體的第一個元素,都被設計成相似的結構體(信號隊列是:q_perm,共享內存是:shm_perm),這些結構體所包含的元素類型,其實和 kern_ipc_perm的結構體元素類型是一樣的。
  • 這就使得我們存儲kern_ipc_perm的指針,即使存了msg_queue的結構體指針,只需要通過強制類型轉換,也是可以訪問msg_queue結構體
  • 這樣對SYSYTEM V設計下的共享內存,信號隊列等可以統一管理
    上面這種內核的設計:實際就是利用了C語言的特點,實現了多態,有種通過父類指針訪問子類的類似

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

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

相關文章

排序(4)——堆排序

目錄 堆排序&#xff08;回顧&#xff09; 基本思路 代碼實現 向下調整排序 AdjustDown 建堆排序 時間復雜度 特性總結 堆排序&#xff08;回顧&#xff09; 重點回顧戳&#x1f449;堆排序 基本思路 堆排序(Heapsort)是指利用堆積樹&#xff08;堆&#xff09;這種數…

SOCKS5代理、代理IP與網絡安全的奇妙旅程

在數字時代&#xff0c;互聯網安全和隱私成為了熱門話題。從個人瀏覽習慣到企業數據保護&#xff0c;每個人都希望他們的在線活動既安全又私密。在這個背景下&#xff0c;了解SOCKS5代理、代理IP、HTTP協議和網絡安全的基礎知識變得尤為重要。 什么是SOCKS5代理&#xff1f; SO…

鴻蒙系統開發適配注意事項

鴻蒙操作系統&#xff08;HarmonyOS&#xff09;的軟件適配涉及到一些特定的注意事項&#xff0c;以確保應用程序在該操作系統上的正常運行和最佳性能。以下是適配鴻蒙軟件時需要注意的一些關鍵問題&#xff0c;希望對大家有所幫助。北京木奇移動技術有限公司&#xff0c;專業的…

MySQL篇—執行計劃介紹(第二篇,總共三篇)

??博主介紹??&#xff1a; ?又是一天沒白過&#xff0c;我是奈斯&#xff0c;DBA一名? ???擅長Oracle、MySQL、SQLserver、Linux&#xff0c;也在積極的擴展IT方向的其他知識面??? ??????大佬們都喜歡靜靜的看文章&#xff0c;并且也會默默的點贊收藏加關注?…

Python 編輯工具 Jupyter notebook

Jupyter notebook Jupyter Notebook是基于網頁的用于交互計算的應用程序。其可被應用于全過程計算&#xff1a;開發、文檔編寫、運行代碼和展示結果。——Jupyter Notebook官方介紹 官網&#xff1a;Project Jupyter | Home Jupyter Notebook 是一個開源的交互式計算環境&#…

dockerdocker-copose_限制容器cpu和內存

本文目錄 docker的限制方式限制CPU占用限制內存占用 docker-compose docker的限制方式 限制CPU占用 Docker使用--cpus參數來限制容器的CPU資源。該參數指定了分配給容器的CPU核心數量或百分比。 例子&#xff1a;限制CPU使用個數 docker run --cpus2 <imageName>以上…

網頁版圖像處理軟件開發服務:助您項目在市場競爭中脫穎而出

在當今數字化時代&#xff0c;圖像處理在各個行業中扮演著重要的角色&#xff0c;虎克專注于提供定制化的網頁版圖像處理軟件開發服務&#xff0c;為您的項目保駕護航。 1.網頁版圖像處理軟件的定制化需求 1.1行業特定功能 針對不同的業務需求&#xff0c;深入了解行業特點&…

springboot基于web的酒店客房管理系統論文

基于web的酒店客房管理系統 摘要 隨著信息技術在管理上越來越深入而廣泛的應用&#xff0c;管理信息系統的實施在技術上已逐步成熟。本文介紹了酒店客房管理系統的開發全過程。通過分析酒店客房管理系統管理的不足&#xff0c;創建了一個計算機管理酒店客房管理系統的方案。文…

Redis 之八:Jdeis API 的使用(Java 操作 Redis)

Jedis API 使用 Jedis 是 Redis 官方推薦的 Java 客戶端&#xff0c;它提供了一套豐富的 API 來操作 Redis 服務器。通過 Jedis API&#xff0c;開發者可以方便地在 Java 應用程序中執行 Redis 的命令來實現數據的增刪查改以及各種復雜的數據結構操作。 以下是一些基本的 Jedis…

springboot網站開發-idea開發環境下無法開啟調試Debug模式

springboot網站開發-idea開發環境下無法開啟調試Debug模式的解決辦法。 近期在寫后端代碼的時候&#xff0c;發現&#xff0c;無法開啟調試模式。網上查詢了一下資料&#xff0c;發現需要做如下修改即可開啟調試模式。 如圖所示&#xff0c;把里面的選項&#xff0c;都放棄勾選…

SQLPro Studio:數據庫管理的革命性工具 mac版

SQLPro Studio是一款強大的數據庫管理和開發工具&#xff0c;它旨在提供高效、便捷和安全的數據庫操作體驗。無論是數據庫管理員、開發人員還是數據分析師&#xff0c;SQLPro Studio都能滿足他們在數據庫管理、查詢、設計和維護方面的需求。 SQLPro Studio mac版軟件獲取 首先…

B樹系列(詳解)

目錄 一、B-樹 二、B樹 三、B*樹 四、時間復雜度 五、Mysql與B樹系列 一、B-樹 首先再說B樹的性質以及其他的之前&#xff0c;先要說一聲&#xff0c;好多人都把這個樹叫B減樹&#xff0c;其實不是&#xff0c;他就叫B樹&#xff0c;至于原因我覺的沒必要再這個名字上糾結…

docker 轉為docker-compose(composerize 命令)

可以使用Composerize將Docker命令轉換為Docker Compose文件。 例如&#xff1a;將docker run命令轉換為Docker Compose格式&#xff0c;只需用Composerize運行它&#xff0c;如下所示&#xff1a; composerize docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/…

【JavaSE】異常

異常概述 異常指的是程序在執行的過程中&#xff0c;出現的非正常情況&#xff0c;如果不處理最終會導致JVM的非正常停止。 在Java中&#xff0c;使用不同的類來表示不同的異常&#xff08;正所謂萬物皆對象&#xff0c;因此異常也使用類來表示&#xff09;。一旦程序出現某種…

【HTML】HTML基礎5(特殊字符)

目錄 特殊字符的作用 常用的特殊字符 使用效果 特殊字符的作用 例如 當我在兩個文字間打出空格時 <p>“銀河護衛隊”系列 在漫威電影宇宙中一直是異數般的存在&#xff0c;不僅因為影片主角是一群反英雄&#xff0c;<strong>與超級英雄相比顯得格格不入<…

讀書筆記-三國演義-三英戰呂布

三英戰呂布是《三國演義》中的一段著名戰役&#xff0c;張飛、關羽和劉備三兄弟聯手擊敗了當時的霸主呂布&#xff0c;展現了他們的武藝和忠義。 介紹 "三英戰呂布"是《三國演義》中的一個著名戰役&#xff0c;發生在三國時期&#xff0c;講述了三位蜀漢名將——劉…

LeetCode 刷題 [C++] 第347題.前 K 個高頻元素

題目描述 給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回其中出現頻率前 k 高的元素。你可以按 任意順序 返回答案。 題目分析 據題意可知&#xff0c;我們需要先遍歷整個數組&#xff0c;并統計每個數字出現的次數&#xff0c;保存在哈希表中&#xff1b;對元素…

synchrosized 的可重入特性、死鎖、哲學家就餐問題以及解決死鎖的方法等干貨

文章目錄 &#x1f490;synchrosized的可重入特性關于死鎖&#xff1a;哲學家就餐問題&#x1f4a1;如何避免/解決死鎖 &#x1f490;synchrosized的可重入特性 可重入特性&#xff1a;當一個線程針對一個對象同時加鎖多次&#xff0c;不會構成死鎖&#xff0c;這樣的特性稱為…

前端學習第一天-html基礎

達標要求 網頁的形成過程 常用的瀏覽器及常見的瀏覽器內核 web 標準三層組成 什么是HTML 熟練掌握HTML文檔結構 熟練掌握HTML常用標簽 1. 初識web前端 Web前端是創建Web頁面或App等前端界面呈現給用戶的過程。 Web前端開發是從網頁制作演變而來&#xff0c;早期網站主…

sklearn.preprocessing.RobustScaler(解釋和原理,分位數,四分位差)

提示&#xff1a;sklearn.preprocessing.RobustScaler&#xff08;解釋和原理&#xff0c;分位數&#xff0c;四分位差&#xff09; 文章目錄 [TOC](文章目錄) 一、RobustScaler 是什么&#xff1f;二、代碼1.代碼2.輸出結果 總結 提示&#xff1a;以下是本篇文章正文內容&…