進程間通訊的四種方式

文章目錄

  • 共享內存
  • 信號
  • 管道
  • 消息隊列

通信方法 無法介于內核態與用戶態的原因
管道(不包括命名管道) 局限于父子進程間的通信。
消息隊列 在硬、軟中斷中無法無阻塞地接收數據。
信號量 無法介于內核態和用戶態使用。
共享內存 需要信號量輔助,而信號量又無法使用。

共享內存

共享內存是最快的進程間通訊的方式

  • 原因:相對于其他幾種方式,共享內存直接在進程的虛擬地址空間進行操作,不再通過執行進入內核的系統調用來傳遞彼此的數據
    在這里插入圖片描述

  • shmget函數

功能用來創建共享內存
原型int shmget(key_t key, size_t size, int shmflg);
參數key:這個共享內存段名字
size:共享內存大小
shmflg:由九個權限標志構成,它們的用法和創建文件時使用的mode模式標志是一樣的
返回值:成功返回?一個?非負整數,即該共享內存段的標識碼;失敗返回-1
  • shmat函數
功能:將共享內存段連接到進程地址空間
原型void *shmat(int shmid, const void *shmaddr, int shmflg);
參數shmid:共享內存標識
shmaddr:指定連接的地址
shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回?一個指針,指向共享內存第?一個節;失敗返回-1
  • shmctl函數
功能:?用于控制共享內存
原型int shmctl(int shmid, int cmd, struct shmid_ds *buf);
參數shmid:由shmget返回的共享內存標識碼
cmd:將要采取的動作(有三個可取值)
buf:指向?一個保存著共享內存的模式狀態和訪問權限的數據結構
返回值:成功返回0;失敗返回-1
  • shmdt函數
功能:將共享內存段與當前進程脫離
原型int shmdt(const void *shmaddr);
參數shmaddr:由shmat所返回的指針
返回值:成功返回0;失敗返回-1
注意:將共享內存段與當前進程脫離不等于刪除共享內存段
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h>typedef struct _Teacher
{char name[64];int age;
}Teacher;int main(int argc, char *argv[])
{int ret = 0;int    shmid;//創建共享內存 ,相當于打開文件,文件不存在則創建shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT | 0666); if (shmid == -1){perror("shmget err");return errno;}printf("shmid:%d \n", shmid);Teacher *p = NULL;//將共享內存段連接到進程地址空間p = shmat(shmid, NULL, 0);//第二個參數shmaddr為NULL,核心自動選擇一個地址if (p == (void *)-1 ){perror("shmget err");return errno;}strcpy(p->name, "aaaa");p->age = 33;//將共享內存段與當前進程脫離shmdt(p);printf("鍵入1 刪除共享內存,其他不刪除\n");int num;scanf("%d", &num);if (num == 1){//用于控制共享內存ret = shmctl(shmid, IPC_RMID, NULL);//IPC_RMID為刪除內存段if (ret < 0){perror("rmerrr\n");}}                 return 0;    
}
#include<stdio.h>
#include<stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<string.h>
#include<errno.h>typedef struct _Teacher
{char name[64];int age;
}Teacher;int main(int argc, char *argv[])
{int ret = 0;int    shmid;//shmid = shmget(0x2234, sizeof(Teacher), IPC_CREAT |IPC_EXCL | 0666); //打開獲取共享內存shmid = shmget(0x2234, 0, 0); if (shmid == -1){perror("shmget err");return errno;}printf("shmid:%d \n", shmid);Teacher *p = NULL;//將共享內存段連接到進程地址空間p = shmat(shmid, NULL, 0);if (p == (void *)-1 ){perror("shmget err");return errno;}printf("name:%s\n", p->name);printf("age:%d \n", p->age);//將共享內存段與當前進程脫離shmdt(p);printf("鍵入1 程序暫停,其他退出\n");int num;scanf("%d", &num);if (num == 1){pause();}                return 0;
}

選取簡單的代碼,可運行觀察效果

信號

信號量和以前的IPC通信方式不同,信號量的本質是計數器,用于多進程對共享數據對象的訪問。

在進程訪問臨界資源之前,需要測試信號量,如果為正數,則信號量-1并且進程可以進入臨界區,若為非正數,則進程掛起放入等待隊列,直至有進程退出臨界區,釋放資源并+1信號量,此時喚醒等待隊列的進程。

信號量本身就是臨界資源,所以必須是原子操作。

  • 生產者消費者模型:
    https://blog.csdn.net/csdn_kou/article/details/81240666

管道

單向,一端輸入,另一端輸出,先進先出FIFO。管道也是文件。管道大小4096字節。

  • 特點:管道滿時,寫阻塞;空時,讀阻塞。
  • 分類:普通管道(僅父子進程間通信)位于內存;命名管道位于文件系統,沒有親緣關系管道只要知道管道名也可以通訊。
  • 管道是由內核管理的一個緩沖區(buffer),相當于我們放入內存中的一個紙條。管道的一端連接一個進程的輸出。這個進程會向管道中放入信息。管道的另一端連接一個進程的輸入,這個進程取出被放入管道的信息。一個緩沖區不需要很大,它被設計成為環形的數據結構,以便管道可以被循環利用。當管道中沒有信息的話,從管道中讀取的進程會等待,直到另一端的進程放入信息。當管道被放滿信息的時候,嘗試放入信息的進程會等待,直到另一端的進程取出信息。當兩個進程都終結的時候,管道也自動消失在這里插入圖片描述
  • 匿名管道與命名管道的區別
    • 匿名管道由pipe函數創建并打開。
    • 命名管道由mkfifo函數創建,打開用open
    • FIFO(命名管道)與pipe(匿名管道)之間唯一的區別在它們創建與打開的方式不同,一但這些工作完成之后,它們具有相同的語義。

消息隊列

消息隊列是先進先出FIFO原則
ipcs & ipcrm命令

  • ipcs: 顯示IPC資源
  • ipcrm: 手動刪除IPC資源
    在這里插入圖片描述

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

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

相關文章

TCP/IP四層模型

文章目錄TCP/IP協議族體系結構以及主要協議數據鏈路層網絡層傳輸層應用層TCP/IP協議族體系結構以及主要協議 TCP/IP協議族是一個四層協議系統&#xff0c;自底而上分別是數據鏈路層、網絡層、傳輸層和應用層。每一層完成不同 的功能&#xff0c;且通過若干協議來實現&#xff…

C++ STL 容器之stack簡單使用

#include <iostream> #include <stack> #include <string> using namespace std; void test1() {stack<int> s;s.push(10);s.push(20);s.push(30);while (s.size()) {cout << "stack top is" << s.top() << endl; // 棧頂…

LRU緩存算法緩存設計和實現

什么是緩存&#xff1f; 舉個例子&#xff0c;去圖書館查資料&#xff0c;一般情況下我們會集中把我們有可能查閱的幾本書從書架取下來&#xff0c;放在我們的桌面上&#xff0c;以便交叉查閱&#xff0c;從而避免頻繁的從座位上跑到書架旁去取書。在這個例子里&#xff0c;書…

C++ STL 容器之queue

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<queue> using namespace std;/*Queue所有元素的進出都必須符合”先進先出”的條件&#xff0c; 只有queue的頂端元素&#xff0c; 才有機會被外界取用。 Queue不提供遍歷功能&#xff0c; 也不提供迭…

牛客網選擇題之并發

在分時操作系統中&#xff0c;進程調度采用&#xff08;&#xff09;算法 時間片輪轉某系統中有 3 個并發進程&#xff0c;都需要同類資源 4 個&#xff0c;試問該系統不會發生死鎖的最少資源數是&#xff1a;9 有n個進程&#xff0c;共享的同類資源數為m&#xff0c;則避免死鎖…

牛客網選擇題之linux

1.在RHEL5系統中&#xff0c;小王希望將他執行的ls命令的輸出結果保存在當前目錄下文件output.ls中&#xff0c;以供日后進行分析和使用&#xff0c;但要求不覆蓋原文件的內容&#xff0c;他應該使用的命令是&#xff08; &#xff09; ls>>output.ls > …

C++ STL容器之 list 初步

#include <iostream> #include<algorithm> #include <string> #include <list> using namespace std;//3.6.4.1 list構造函數 //list<T> lstT;//list采用采用模板類實現,對象的默認構造形式&#xff1a; //list(beg, end);//構造函數將[beg, end…

C++ STL容器值set

/* 3.7.2 set常用API 3.7.2.1 set構造函數 set<T> st;//set默認構造函數&#xff1a; mulitset<T> mst; //multiset默認構造函數: set(const set& st);//拷貝構造函數 3.7.2.2 set賦值操作 set & operator(const set & st);//重載等號操作符 swap(st)…

C++ STL容器之map 簡單使用

3.8.2.1 map構造函數 map<T1, T2> mapTT;//map默認構造函數: map(const map &mp);//拷貝構造函數3.8.2.2 map賦值操作 map& operator(const map &mp);//重載等號操作符 swap(mp);//交換兩個集合容器3.8.2.3 map大小操作 size();//返回容器中元素的數目 empty…

Manacher算法圖解

看了好久的Manacher算法&#xff0c;覺得還是要自己畫一遍&#xff0c;自己把代碼寫一遍才能理解 下面分享一下&#xff0c;如果有錯&#xff0c;希望指正 簡陋版本的&#xff0c;但是他基本只是做到了求取最長回文字符串&#xff0c;嚴格來說它并不是Manacher’s Algorithm-…

Flink 客戶端操作命令及可視化工具

Flink提供了豐富的客戶端操作來提交任務和與任務進行交互。下面主要從Flink命令行、Scala Shell、SQL Client、Restful API和 Web五個方面進行整理。 在Flink安裝目錄的bin目錄下可以看到flink&#xff0c;start-scala-shell.sh和sql-client.sh等文件&#xff0c;這些都是客戶…

ySQL挑戰搭建一個簡易的成績管理系統的數據庫

文章為自己搜索網上資源&#xff0c;再在這里進行整理&#xff0c;所以標注為轉載 [實驗步驟](https://www.shiyanlou.com/courses/reports/1347700) 總結做實驗注意事項&#xff1a; 1.添加主鍵 2.主鍵和外鍵的關系 3.注意自增的書寫添加 mysql 如何修改、添加、刪除表主鍵…

網絡之DNS協議圖解

DNS是計算機域名系統 (Domain Name System) 域名系統采用類似目錄樹的等級結構。 域名服務器是指保存有該網絡中所有主機的域名和對應IP地址&#xff0c;并具有將域名轉換為IP地址功能的服務器。 域名服務器為客戶機/服務器模式中的服務器方&#xff0c;它主要有兩種形式&am…

C++ 謂詞,

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <vector> #include <algorithm> using namespace std;class GreaterThen20 { public:bool operator()(int val){return val > 20;} };//一元謂詞 void test01() {vector<int>v;v.push…

網絡之ARP

地址解析協議&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根據IP地址獲取物理地址的一個TCP/IP協議。 主機發送信息時將包含目標IP地址的ARP請求廣播到網絡上的所有主機&#xff0c;并接收返回消息&#xff0c;以此確定目標的物理地址…

C++ 內建函數對象

STL內建了一些函數對象。分為:算數類函數對象,關系運算類函數對象&#xff0c;邏輯運算類仿函數。這些仿函數所產生的對象&#xff0c;用法和一般函數完全相同&#xff0c;當然我們還可以產生無名的臨時對象來履行函數功能。使用內建函數對象&#xff0c;需要引入頭文件 functi…

網絡之ICMP協議

ICMP 主要功能&#xff1a; 確認IP包是否成功送達目標地址通知在發送過程當中IP包被廢棄的具體原因改善網絡設置等 在IP通信中如果某個IP包因為某種原因未到達目標地址&#xff0c;那么這個原因由ICMP通知。 過程&#xff08;圖解TCP/IP&#xff09; ICMP類型 常見的&am…

C++ 常用算法之遍歷

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> #include <vector> #include <functional> using namespace std;/* 遍歷算法 遍歷容器元素 param beg 開始迭代器 param end 結束迭代器 param _callback 函數回調或者函數…

網絡之NAT協議

由來&#xff1a; 2011年2月3日中國農歷新年&#xff0c; IANA對外宣布&#xff1a;IPv4地址空間最后5個地址塊已經被分配給下屬的5個地區委員會。2011年4月15日&#xff0c;亞太區委員會APNIC對外宣布&#xff0c;除了個別保留地址外&#xff0c;本區域所有的IPv4地址基本耗盡…

C++ 常用查找算法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> using namespace std; #include <vector> #include <string> #include <functional> /* find算法 查找元素 param beg 容器開始迭代器 param end 容器結束迭代器 para…