波奇學Linux:進程通信管道

?進程通信

管道:基于文件級別的單向通信

創建父子進程,使得進程的struct file*fd_array[]的文件描述符指向同一個struct file文件,這個文件是內存級文件。

父進程關寫端,子進程再關閉讀端。實現單向通信

子進程寫入,父進程讀取。

如果進程不是父子關系,則無法利用管道,因此管道應用于父子或者兄弟進程

以上的管道叫做匿名管道。

創建管道:pipe

輸出型參數

pipefd[0]讀下標

pipefd[1]寫下標

代碼示例

#include <iostream>
#include<string>
#include<cstdlib>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>using namespace std;
#define N 2
#define NUM 1024
void Writer(int wfd)
{string s="hello I am child";pid_t self=getpid();int number=0;char buffer[NUM];while(true){buffer[0]=0; //字符串清空//將字符串的內容放入buffer緩沖區中snprintf(buffer,sizeof(buffer),"%s-%d-%d",s.c_str(),self,number++);cout<<buffer<<endl;// 發送給父進程write(wfd,buffer,strlen(buffer));sleep(1);}
}
void Reader(int rfd)
{char buffer[NUM];while(true){buffer[0]=0;// n表示實際讀到字節的大小ssize_t n=read(rfd,buffer,sizeof(buffer));if(n>0){buffer[n]=0; //當成字符串加入"\0"cout<<"father get a message["<<getpid()<<"]#"<<buffer<<endl;}}
}
int main()
{int pipefd[]={0};int n=pipe(pipefd);if(n<0) return 1;cout<<"pipefd[0]:"<<pipefd[0]<<", pipefd[1]: "<<pipefd[1]<<endl;pid_t id=fork();if(id<0) return 2;if(id==0) {close(pipefd[0]);//IPC codeWriter(pipefd[1]);close(pipefd[1]);exit(0);}close(pipefd[1]);Reader(pipefd[0]);pid_t rid=waitpid(id,nullptr,0);if(rid<0) return 3;close(pipefd[0]);return 0;
}

然而多執行流會會出現訪問沖突的問題--父進程訪問的數據到一半時,舊數據被寫端覆蓋。

父子進程協同,保護管道文件數據安全

讀寫端正常,如果管道為空,讀端阻塞

管道文件有大小,寫滿寫端阻塞

讀端正常讀,寫端關閉,寫進程變成僵尸進程,讀端就會讀到0,表明讀到文件結尾,而且不會阻塞

寫端正常寫,讀端關閉,操作系統通過信號殺掉寫入的進程。

ulimit查看pipe size大小,但是不同內核可能有差別

管道面向字節流,一次性讀完,有多少讀多少,且將分割符看成一個普通字符,管道規范可以解決這個問題

管道是基于文件的,文件的生命周期是隨進程的

管道的應用場景

使用管道實現簡易版本的進程池

?Task.hpp

#pragma once
#include<cstdlib>
#include<iostream>
#include<vector>
#include<unistd.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string>
typedef void (*task_t)();
std::vector<task_t> tasks;//任務是四個函數
void task1()
{std::cout<<"task 1 call"<<std::endl;
}
void task2()
{std::cout<<"task 2 call"<<std::endl;
}
void task3()
{std::cout<<"task 3 call"<<std::endl;
}
void task4()
{std::cout<<"task 4 call"<<std::endl;
}
// const & 輸入 ->向函數內部輸入
// * 輸出
// & 輸入 輸出
void LoadTask(std::vector<task_t> *p_tasks)
{p_tasks->push_back(&task1);p_tasks->push_back(&task2);p_tasks->push_back(&task3);p_tasks->push_back(&task4);
}

?ProcessPool.cc

#include "Task.hpp"
//對管道進行描述#define processnum 10
class channel
{
public:channel(int task_id,int pid,std::string processname):_cmdfd(task_id),_pid(pid),_processname(processname){}
public:int _cmdfd;int _pid;std::string _processname;
};
std::vector<channel> channels;
void slaver()
{while(true){int tasknum=0;ssize_t num=read(0,&tasknum,sizeof(int));//read block,等待輸入// tasknum=tasknum%tasks.size();// (*tasks[tasknum])();//std::cout<<"i and pid"<<i<<pid<<std::endl;if (!num)break;else{std::cout<<"child process "<<getpid()<<"pid: "<<"receive task_id: "<<tasknum<<std::endl;(*tasks[tasknum])();}}
}
void InitProcessPool(std::vector<channel>* pchannels)
{std::vector<int> oldfds;for (int i=0;i<processnum;i++){//create pipeint pipefd[2];int n=pipe(pipefd);assert(!n); // n=0 successpid_t pid=fork();assert(pid!=-1); //pid =-1 fail//child//std::cout<<"i = "<<i;if(pid==0){   std::cout<<"child process:"<<getpid()<<"have otherfds: ";//only one write fdfor(auto oldfd:oldfds){std::cout<<oldfd<<" ";close(oldfd);}std::cout<<std::endl;//build relationshipclose(pipefd[1]);// pipe read from fd=0 not fd=3;dup2(pipefd[0],0);close(pipefd[0]);// slaver();exit(0);}close(pipefd[0]);int status=0;// ensure one by one ,block until child process finish// pid_t result=waitpid(pid,&status,0);// assert(result!=-1);pchannels->push_back(channel(pipefd[1],pid,"process "+std::to_string(i)));oldfds.push_back(pipefd[1]);sleep(1);}}
void menu()
{std::cout<<"*********************"<<std::endl;std::cout<<"******1.task one*****"<<std::endl;std::cout<<"******2.task two*****"<<std::endl;std::cout<<"******3.task three***"<<std::endl;std::cout<<"******4.task four****"<<std::endl;std::cout<<"******0.quit*********"<<std::endl;std::cout<<"*********************"<<std::endl;
}
void ctrlSlaver()
{int which=0;while(true){menu();int enter=0;std::cout<<"enter number:";std::cin>>enter;std::cout<<std::endl;if (enter==0){std::cout<<"quit software"<<std::endl;//ssize_t n=write(0,&enter,0); 不用寫入,直接退出就好了//assert(n!=-1);break;}ssize_t n=write(channels[which]._cmdfd,&enter,sizeof(int));assert(n!=-1);std::cout<<"parent send a task_num "<<enter<<" to process "<<channels[which]._processname<<std::endl;which++;which=which%processnum;}
}
void quitProcess(std::vector<channel>& pchannels)
{for(auto channel:channels){std::cout<<"close process"<<channel._pid<<std::endl;//關閉讀端,進程關閉close(channel._cmdfd);wait(NULL);}}
void PrintTask(const std::vector<task_t> tasks)
{for(auto task:tasks){(*task)();}}
int main()
{// load the taskLoadTask(&tasks);//PrintTask(tasks);InitProcessPool(&channels);ctrlSlaver();quitProcess(channels);return 0;
}

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

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

相關文章

Java面向對象(三)

一、封裝&#xff1a; 一般意義的封裝&#xff1a;把一段重復代碼抽取成一個函數&#xff0c;稱為代碼的封裝&#xff08;包裝&#xff09;面向對象語言的封裝&#xff1a;將類的某些信息隱藏在類的內部&#xff08;通過使用不同的訪問權限修飾符&#xff09;&#xff0c;不許…

C++ Primer 筆記(總結,摘要,概括)——第3章 字符串、向量和數組

目錄 3.1 命名空間的using聲明 3.2 標準庫類型string 3.2.1 定義和初始化string對象 3.2.2 string對象上的操作 3.2.3 處理string對象中的字符 3.3 標準庫類型vector 3.3.1 定義和初始化vector對象 3.3.2 向vector對象中添加元素 3.3.3 其他vector操作 3.4 迭代器介紹 3.4.…

如何使用rocketmq實現分布式事務?

什么是rocketmq事務消息 事務消息是 Apache RocketMQ 提供的一種高級消息類型&#xff0c;支持在分布式場景下保障消息生產和本地事務的最終一致性。 RocketMQ的分布式事務又稱為“半消息事務”。 事務消息處理流程 RocketMQ是靠半消息機制實現分布式事務 事務消息&#x…

Spring之AOP源碼解析(上)

Aop相關注解 EnableTransactionManagementEnableAspectJAutoProxyEnableAsync... 從注解切入來看看這些注解都干了什么 Import注解作用簡述 注入的類一般繼承ImportSelector或者ImportBeanDefinitionRegistrar接口 繼承ImportSelector接口&#xff1a;selectImports方法返回…

pandas/geopandas 筆記:判斷地點在不在路網上 不在路網的點和路網的距離

0 導入庫 import osimport pandas as pd pd.set_option(display.max_rows,5)import osmnx as oximport geopandas as gpd from shapely.geometry import Point 1 讀取數據 假設我們有 如下的數據&#xff1a; 1.1 新加坡室外基站位置數據 cell_stationpd.read_csv(outdoor…

TSINGSEE青犀AI智能分析網關V4初始配置與算法相關配置介紹

TSINGSEE青犀AI智能分析網關V4內置了近40種AI算法模型&#xff0c;支持對接入的視頻圖像進行人、車、物、行為等實時檢測分析&#xff0c;上報識別結果&#xff0c;并能進行語音告警播放。硬件管理平臺支持RTSP、GB28181協議、以及廠家私有協議接入&#xff0c;可兼容市面上常見…

通過例子學習golang的Goroutine

Go 語言中的 Goroutine 是一種輕量級的并發執行單位。它可以與其他 Goroutine 并發地執行&#xff0c;而不需要顯式地管理線程的創建和銷毀。Goroutine 是 Go 語言并發模型的核心組成部分&#xff0c;它使得編寫并發程序變得更加簡單和高效。 例一 創建兩個function&#xff0…

linux下ffmpeg調用GPU硬件解碼(VDPAU/VAAPI)保存文件

本文講解在linux下面&#xff0c;如何通過ffmpeg調用GPU硬件解碼&#xff0c;并保存解碼完的yuv文件。 其實&#xff0c;ffmpeg自帶的例子hw_decode.c這個文件&#xff0c;就已經能滿足要求了&#xff0c;因此&#xff0c;本文就嘗試講解以下hw_decode這個例子。hw_decode.c可以…

watchpoint

前言 內存被踩&#xff0c;通過 watchpoint 找到真兇 實例 以 smsc911x 網卡驅動為基體&#xff0c;進行實驗&#xff0c;和網卡本身功能無關&#xff0c; 每執行一次 ifconfig eth0 up&#xff0c;就會調用一次 smsc911x_open()&#xff0c;我在這里設計了一段代碼&#xf…

數學知識(四)(容斥原理、博弈論)

一、容斥原理 容斥原理公式 一共加或者減的式子個數 &#xff08;一&#xff09;利用容斥原理解決求能被質數整除的數的個數 890計算能被整除的數的個數 因為一共有2^n-1種選法&#xff0c;可以用位運算的方式枚舉&#xff0c;對于得到的每一種選法&#xff0c;根據存在的數…

六、回歸與聚類算法 - 邏輯回歸與二分類

線性回歸欠擬合與過擬合線性回歸的改進 - 嶺回歸分類算法&#xff1a;邏輯回歸模型保存與加載無監督學習&#xff1a;K-means算法 1、應用場景 2、原理 2.1 輸入 2.2 激活函數 3、損失以及優化 3.1 損失 3.2 優化 4、邏輯回歸API 5、分類的評估方法 5.1 精確率和召回率 5.2…

找出作弊的人

文章目錄 題目描述輸入描述輸出描述樣例1解釋:樣例2代碼 題目描述 公司組織了一次考試,現在考試結果出來了&#xff0c;想看一下有沒人存在作弊行為,但是員工太多了,需要先對員工進行一次過濾,再進一步確定是否存在作弊行為。 過濾的規則為:找到分差最小的員工ID對(p1,p2)列表…

【Spring】IoC容器 控制反轉 與 DI依賴注入 配置類實現版本 第四期

文章目錄 基于 配置類 方式管理 Bean一、 配置類和掃描注解二、Bean定義組件三、高級特性&#xff1a;Bean注解細節四、高級特性&#xff1a;Import擴展五、基于注解配置類方式整合三層架構組件總結 基于 配置類 方式管理 Bean Spring 完全注解配置&#xff08;Fully Annotatio…

Kotlin學習 6

1.接口 interface Movable {var maxSpeed: Intvar wheels: Intfun move(movable: Movable): String}class Car(var name: String, override var wheels: Int 4, _maxSpeed: Int) : Movable {override var maxSpeed: Int _maxSpeedget() fieldset(value) {field value}overr…

C語言讀取 ini 配置文件,修改/添加鍵值對

C語言讀取 ini 配置文件&#xff0c;修改/添加鍵值對 C語言讀取 ini 配置文件&#xff0c;對section中的鍵值對進行修改/添加&#xff0c;如果section不存在&#xff0c;則在末尾將新的section/key/value 添加進去。 一、了解什么是INI文件&#xff1f; ini 文件是Initializ…

【大數據】Flink 之部署篇

Flink 之部署篇 1.概述和參考架構2.可重復的資源清理3.部署模式3.1 Application 模式3.2 Per-Job 模式&#xff08;已廢棄&#xff09;3.3 Session 模式 Flink 是一個多用途框架&#xff0c;支持多種不同的混合部署方案。下面&#xff0c;我們將簡要介紹 Flink 集群的構建模塊、…

流動資金貸款管理辦法

流動資金貸款管理辦法 (2024年1月30日國家金融監督管理總局令2024年第2號公布 自2024年7月1日起施行) 第一章 總 則 第一條 為規范銀行業金融機構流動資金貸款業務經營行為&#xff0c;加強流動資金貸款審慎經營管理&#xff0c;促進流動資金貸款業務健康發展&#xff0c;依…

【html學習筆記】3.表單元素

1.文本框 1.1 語法 <input type "text">表示文本框。且只能寫一行 1.2 屬性 使用屬性size 設置文本框大小 <input type"text" size"10">2. 使用屬性value 來設置文本框的默認文字 <input type"text" size"…

Vue狀態管理庫-Pinia

一、Pinia是什么&#xff1f; Pinia 是 Vue 的專屬狀態管理庫&#xff0c;它允許支持跨組件或頁面共享狀態&#xff0c;即共享數據&#xff0c;他的初始設計目的是設計一個支持組合式API的 Vue 狀態管理庫&#xff08;因為vue3一個很大的改變就是組合式API&#xff09;,當然這…

PFA三角燒瓶實驗室PFA錐形瓶本底純凈耐腐蝕性強

PFA三角燒瓶外觀呈平底圓錐狀&#xff0c;下闊上狹&#xff0c;有一圓柱形頸部&#xff0c;上方有一較頸部闊的開口&#xff0c;可用塞子封閉。PFA三角燒瓶也稱PFA錐形瓶&#xff0c;PFA反應瓶&#xff0c;PFA三角燒瓶、PFA依氏燒瓶、PFA錐形燒瓶&#xff0c;PFA鄂倫麥爾瓶等。…