中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

公司微網(wǎng)站怎么建設(shè)網(wǎng)站關(guān)鍵詞公司

公司微網(wǎng)站怎么建設(shè),網(wǎng)站關(guān)鍵詞公司,體驗(yàn)比較好的網(wǎng)站,黃山找人做網(wǎng)站目錄 前言 1.進(jìn)程間通信理論 2.使用管道進(jìn)行通信 3.管道的一些信息 4.應(yīng)用場(chǎng)景:進(jìn)程池(基于匿名管道) 5.命名管道 6.總結(jié) 前言 本篇我們開(kāi)始學(xué)習(xí)linux進(jìn)程間通信相關(guān)的內(nèi)容,第一篇我們要介紹的是進(jìn)程間通信的理論概念以及匿…

目錄

前言

1.進(jìn)程間通信理論

2.使用管道進(jìn)行通信

3.管道的一些信息

4.應(yīng)用場(chǎng)景:進(jìn)程池(基于匿名管道)

5.命名管道

6.總結(jié)


前言

? 本篇我們開(kāi)始學(xué)習(xí)linux進(jìn)程間通信相關(guān)的內(nèi)容,第一篇我們要介紹的是進(jìn)程間通信的理論概念以及匿名、命名管道通信的詳細(xì)操作,并且我們還會(huì)基于匿名管道實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線(xiàn)程池,加油!!

1.進(jìn)程間通信理論

1.什么是通信

image-20250514164645153

進(jìn)程間通信也叫做IPC技術(shù)

image-20250524141716554

發(fā)展:從單機(jī)通信到網(wǎng)絡(luò)通信

如何理解通信的本質(zhì)問(wèn)題:

1.操作系統(tǒng)需要直接或者間接給通信雙方的進(jìn)程提供 ”內(nèi)存空間“

2.要通信的進(jìn)程,必須看到一份公共的資源

通信前提:要先讓不同的進(jìn)程看到同一份資源【某一種“內(nèi)存”】(我們學(xué)通信實(shí)際上是學(xué)這個(gè))

不同的通信種類(lèi):

本質(zhì)就是:上面所說(shuō)的資源,是操作系統(tǒng)的哪一個(gè)模塊提供的

2.為什么要有通信?

有時(shí)候我們是需要多進(jìn)程協(xié)同,然后去完成某種業(yè)務(wù)內(nèi)容比如: cat file | grep 'hello'

3.怎么辦?

進(jìn)程看到的同一份“資源”是由操作系統(tǒng)提供,操作系統(tǒng)需要設(shè)計(jì)統(tǒng)一的通信接口,這個(gè)接口要如何被調(diào)用就是我們的進(jìn)程間通信的方案,原則就是先統(tǒng)一標(biāo)準(zhǔn),后使用

進(jìn)程間通信的方案

采用標(biāo)準(zhǔn)做法:

POSIX —— 讓通信過(guò)程可以跨主機(jī)

System V —— 聚焦在本地通信

采用文件做法讓不同的進(jìn)程看到同一份資源:

1.管道——基于文件系統(tǒng)

a.匿名管道

b.命名管道

什么是管道

image-20250514190328695

匿名管道,不需要IO,不需要刷新到磁盤(pán)上,和磁盤(pán)甚至沒(méi)關(guān)系,為內(nèi)存級(jí)文件,沒(méi)有所謂的名稱(chēng)

image-20250615213742529

兩進(jìn)程分別以讀和寫(xiě)方式打開(kāi)同一個(gè)文件,為了讓子進(jìn)程也能看到讀寫(xiě)端

image-20250514205616028

一般而言,我們的管道只能用來(lái)進(jìn)行單向數(shù)據(jù)通信,所以需要分別把父子進(jìn)程不需要的fd關(guān)閉

匿名管道:目前能用來(lái)進(jìn)行父子進(jìn)程之間進(jìn)程間通信

2.使用管道進(jìn)行通信

管道是被操作系統(tǒng)單獨(dú)設(shè)計(jì)的,需要配上單獨(dú)的系統(tǒng)調(diào)用

管道函數(shù):pipe

其中的pipefd為輸出型參數(shù),用來(lái)存儲(chǔ)打開(kāi)文件后返回的讀寫(xiě)兩個(gè)文件描述符

  • 成功時(shí):返回 0,同時(shí)會(huì)通過(guò)傳入的整數(shù)數(shù)組參數(shù)(如 int pipefd[2])返回兩個(gè)文件描述符,pipefd[0] 用于從管道讀取數(shù)據(jù)(讀端),pipefd[1] 用于向管道寫(xiě)入數(shù)據(jù)(寫(xiě)端)

  • 失敗時(shí):返回 -1,并設(shè)置 errno 變量以標(biāo)識(shí)具體的錯(cuò)誤原因(如文件描述符用盡、參數(shù)地址不合法等)

image-20250515182817992

image-20250516152354886

[^] ?pipefd0是讀取(想象成嘴巴用來(lái)讀),pipefd1是寫(xiě)入(想象成筆用來(lái)寫(xiě))?

我們可以看到創(chuàng)建pipe管道這個(gè)文件時(shí),pipe函數(shù)是不需要傳遞文件路徑的,因?yàn)樗莾?nèi)存級(jí)文件,壓根不需要文件路徑,也就是說(shuō)也不需要文件名,所以叫做匿名管道

那沒(méi)有文件名,要怎么去保證兩個(gè)進(jìn)程打開(kāi)的是同一個(gè)管道文件呢?答:子進(jìn)程繼承父進(jìn)程文件描述符表

各種 ‘printf’

前面幾種的區(qū)別是把內(nèi)容格式化到特定的文件或是字符串內(nèi),第一種printf就是格式化顯示到顯示器上

image-20250516185431273

3.管道的一些信息

管道的5種特性:

  1. 匿名管道只能用來(lái)進(jìn)行具有”血緣關(guān)系“的進(jìn)程進(jìn)行進(jìn)程間通信(通常是父子)

  2. 管道文件,自帶同步機(jī)制(后面多線(xiàn)程詳談)

  3. 管道是面向字節(jié)流

  4. 管道是單向通信的——屬于半雙工的一種特殊情況

    a. 任何一個(gè)時(shí)刻,一個(gè)發(fā),一個(gè)收——半雙工

    b. 任何一個(gè)時(shí)刻,可以同時(shí)發(fā)收——全雙工

  5. (管道)文件的生命周期是隨進(jìn)程的,進(jìn)程一旦結(jié)束,所打開(kāi)的文件就被操作系統(tǒng)關(guān)閉

管道的4種通信情況:

  1. 寫(xiě)慢,讀快——讀端就要阻塞(進(jìn)程),要等寫(xiě)端

  2. 寫(xiě)快,讀慢——寫(xiě)端就要阻塞(進(jìn)程),要等讀端

    以上兩種情況是因?yàn)楣艿赖耐綑C(jī)制這一特性形成的

  3. 寫(xiě)關(guān),繼續(xù)讀——read就會(huì)讀到返回值(\0也就是0),表示文件結(jié)尾,如果讓n=read(),那么n的值此時(shí)就為0

  4. 讀關(guān),繼續(xù)寫(xiě)——寫(xiě)端在寫(xiě)入,沒(méi)有任何意義(os不會(huì)做沒(méi)有意義的事情),所以這種情況發(fā)生之后,操作系統(tǒng)會(huì)殺掉寫(xiě)端進(jìn)程,然后發(fā)送異常信號(hào):13->SIGPIPE

image-20250525154025308

image-20250525154208760

管道的容量

image-20250525161000420

image-20250525160704947

[^] ?也就是65536/1024=64kb?

管道的寫(xiě)入原子性

管道寫(xiě)入的原子性是指:當(dāng)進(jìn)程向管道寫(xiě)入數(shù)據(jù)時(shí),若數(shù)據(jù)量不超過(guò) PIPE_BUF(如 Linux 中為 4096 字節(jié),POSIX 規(guī)定至少 512 字節(jié)),該寫(xiě)入操作要么完全成功(數(shù)據(jù)全部寫(xiě)入),要么完全失敗(數(shù)據(jù)未寫(xiě)入),不會(huì)出現(xiàn)部分寫(xiě)入的情況

image-20250525163105919

4.應(yīng)用場(chǎng)景:進(jìn)程池(基于匿名管道)

池化技術(shù)

可以減少我們創(chuàng)建對(duì)應(yīng)某種資源的成本,提高訪(fǎng)問(wèn)時(shí)的效率

image-20250525164532521

如果父進(jìn)程把所有任務(wù)都分配給一個(gè)子進(jìn)程——負(fù)載不均衡

我們要雨露均沾地分配任務(wù)——負(fù)載均衡

幾種方式實(shí)現(xiàn)均衡

  1. 輪詢(xún)

  2. 隨機(jī)

  3. channel添加負(fù)載指標(biāo)

進(jìn)程池信道的建立

#pragma once
#include <iostream>
#include <cstdlib> //cstdlib->stdlib.h
#include <vector>
#include <unistd.h>
using namespace std;
?
//.hpp后綴可以使得方法實(shí)現(xiàn)和聲明在一個(gè)文件,這樣Main.cc在調(diào)用時(shí)只需要包含.hpp頭文件
?
// 進(jìn)程池
?
// 對(duì)(信道)管道進(jìn)行管理
// 先描述:描述管道信息
class channel
{
public:channel(int fd, pid_t id): _wfd(fd),_subid(id){// 使用to_string將fd和id都轉(zhuǎn)成字符加到后面作為名字一部分_name = "channel-" + to_string(_wfd) + "-" + to_string(_subid);}
?~channel() {}
?// 外部需要拿到channel內(nèi)部的信息,我們需要一些get方法int Fd() { return _wfd; }pid_t SubId() { return _subid; }string Name() { return _name; }
?
private:// 每個(gè)管道都需要有對(duì)應(yīng)的文件描述符int _wfd;// 還需要知道對(duì)應(yīng)的子進(jìn)程的idpid_t _subid;// 以及為了之后方便打印提示消息對(duì)應(yīng)管道的名字string _name;
};?
// 要?jiǎng)?chuàng)建多少個(gè)進(jìn)程池
const int gdefaultnum = 5;
?
// 再組織;管理信道(管道)的接口類(lèi),我們這里通過(guò)vector數(shù)據(jù)結(jié)構(gòu)來(lái)組織
class ChannelManager
{
public:ChannelManager() {}~ChannelManager() {}
?void Insert(int wfd, pid_t subid){// 構(gòu)建一個(gè)channel然后push到組織的vector數(shù)組中(先描述,再組織)// channel c(wfd, subid);//_channels.push_back(move(c)); //c為臨時(shí)對(duì)象,應(yīng)該使用右值引用減少拷貝// 或者也可以使用vector容器中提供的emplace_back方法// 直接調(diào)用內(nèi)部構(gòu)造函數(shù)幫我們創(chuàng)建一個(gè)對(duì)象在插入vector中_channels.emplace_back(wfd, subid);}
?// 打印_channels中各channel的信息的方法void PrintChannels(){for (auto &channel : _channels){cout << channel.Name() << endl;}}
?
private:// 通過(guò)vector來(lái)組織vector<channel> _channels;
};?
// 進(jìn)程池類(lèi)
class ProcessPool
{
public:ProcessPool(int num): _process_num(num){}
?~ProcessPool() {}
?// 子進(jìn)程要做的工作void Work(int rfd){// 偽工作while (true){cout << "我的rfd是: " << rfd << endl;sleep(5);}}
?// 創(chuàng)建進(jìn)程池方法bool Create(){// 要?jiǎng)?chuàng)建process_num個(gè)進(jìn)程for (int i = 0; i < _process_num; i++){// 1. 創(chuàng)建管道int pipefd[2] = {0};int n = pipe(pipefd);if (n < 0){return false;}
?// 2. 創(chuàng)建子進(jìn)程// 子進(jìn)程讀,父進(jìn)程寫(xiě)int subid = fork();if (subid < 0)return false;else if (subid == 0){// 子進(jìn)程// 3. 關(guān)閉寫(xiě)端close(pipefd[1]);Work(pipefd[0]); // 子進(jìn)程要做的讀端相關(guān)工作close(pipefd[0]);
?// 執(zhí)行完直接退出// 不會(huì)干擾for循環(huán),只有父進(jìn)程會(huì)一直循環(huán)創(chuàng)建執(zhí)行循環(huán)內(nèi)代碼exit(0);}else{// 父進(jìn)程// 3. 關(guān)閉讀端close(pipefd[0]);// 需要在ChannelManager內(nèi)部把我們的fd和subid信息傳入創(chuàng)建的channel中// 再由ChannelManager把創(chuàng)建好的channel插入到數(shù)組中// 所以在ChannelManager類(lèi)中需要Insert方法來(lái)完成上述操作// 其中我們父進(jìn)程對(duì)應(yīng)的fd文件描述符是寫(xiě)端:pipefd[1]_cn.Insert(pipefd[1], subid);}}// 創(chuàng)建成功return true;}
?// Debug方法中查看每個(gè)channel信道(管道)的信息void Debug(){// 調(diào)用ChannelManager中的PrintChannels方法_cn.PrintChannels();}
?
private:// 進(jìn)程池類(lèi)內(nèi)部需要包含我們的通信信道// 所以我們通過(guò)管理通信信道的類(lèi)創(chuàng)建一個(gè)對(duì)象在進(jìn)程池內(nèi)部ChannelManager _cn;// 要?jiǎng)?chuàng)建的進(jìn)程池對(duì)應(yīng)的進(jìn)程的個(gè)數(shù),這樣就能確定管道的個(gè)數(shù)int _process_num;
};

image-20250527215423842

image-20250525203708327

采用輪詢(xún)的方式使得負(fù)載平衡

image-20250526130910735

進(jìn)程池相關(guān)完整源代碼可以看:ProcessPool?

5.命名管道

匿名管道只能用來(lái)進(jìn)行具有血緣關(guān)系的進(jìn)程進(jìn)行進(jìn)程間通信(常用于父子進(jìn)程)

如果兩個(gè)進(jìn)程不相關(guān),該如何進(jìn)行通信呢?

image-20250527214338068

image-20250527213403568

通過(guò)上圖其實(shí)我們就已經(jīng)通過(guò)打開(kāi)同一路徑下的同一個(gè)文件來(lái)做到讓不同的進(jìn)程看到了同一份資源(進(jìn)程間通信的前提),而因?yàn)槲募新窂?#xff08;使得這個(gè)路徑下文件具有唯一性,通過(guò)路徑來(lái)區(qū)分)、有名字——所以這種通信的方式叫做——命名管道!

我們一般文件是要刷新到磁盤(pán)的,我們的命名管道這種作為通信的文件是不能被刷新的,所以命名管道需要一種特殊的文件——管道文件(只會(huì)被打開(kāi),不需要刷新)

我們通過(guò)mkfifo命令來(lái)創(chuàng)建管道文件,也就是命名管道

image-20250527215829686

image-20250527220213397

echo和cat在執(zhí)行時(shí)就是進(jìn)程(shell運(yùn)行原理,不管是不是內(nèi)建命令,它都是進(jìn)程)

image-20250527221036033

所以上圖中我們就利用命名管道完成了一次進(jìn)程間通信,echo將"hello fifo"重定向輸入,然后cat重定向輸出從fifo中顯示內(nèi)容到終端上

我們可以通過(guò)unlink命令來(lái)刪除管道文件

image-20250528194032982

image-20250528194117756

我們?cè)诖a上可以通過(guò)mkfifo接口來(lái)創(chuàng)建管道文件

image-20250528112541945

記住這里的第一個(gè)參數(shù)是c語(yǔ)言格式的字符,如果用string對(duì)象,得調(diào)用c_str()

路徑加名字就構(gòu)成我們要構(gòu)建的命名管道了

string fifoname = _path + "/" + _name;

int n = mkfifo(fifoname.c_str(), 0666);

image-20250527222737970

[^] ?上圖內(nèi)容不理解沒(méi)關(guān)系,我們?cè)诰W(wǎng)絡(luò)部分才會(huì)進(jìn)一步去理解?

同樣的,我們?cè)诖a上可以用unlink函數(shù)來(lái)關(guān)閉管道文件

image-20250528164710437

image-20250528164956509

[^] ?關(guān)閉成功返回0,失敗返回-1,和mkfifo創(chuàng)建返回邏輯是一樣的?

簡(jiǎn)單用命名管道通信代碼:

comm.hpp

#pragma once
?
#define FIFO_FILE "fifo"

server.cc

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <fcntl.h>
#include "comm.hpp"
using namespace std;
?
int main()
{umask(0);// 新建管道int n = mkfifo(FIFO_FILE, 0666);if (n != 0){cerr << "mkdir fifo error" << endl;return 1;}cout << "mkfifo success" << endl;
?// 以讀打開(kāi)管道文件// write方?jīng)]有執(zhí)行open時(shí),read方就要在open內(nèi)部阻塞// 直到有人把管道文件打開(kāi)了,open才會(huì)返回int fd = open(FIFO_FILE, O_RDONLY);if (fd < 0){cerr << "open fifo error" << endl;return 2;}cout << "open fifo success" << endl;
?// 正常讀取char buffer[1024];while (true){int number = read(fd, buffer, sizeof(buffer) - 1);if (number > 0){// 我們把讀到內(nèi)容當(dāng)成字符串,所以得在n位置加上\0buffer[number] = '\0';cout << "client say: " << buffer << endl;}else if (number == 0){cout << "client quit! me too " << number << endl;break;}else{cerr << "read error" << endl;break;}}
?// 關(guān)閉管道文件close(fd);
?// 刪除管道文件n = unlink(FIFO_FILE);if (n == 0){cout << "remove fifo success" << endl;}else{cout << "remove fifo failed" << endl;}
?return 0;
}

client.cc

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <fcntl.h>
#include "comm.hpp"
using namespace std;
?
int main()
{// client端不需要?jiǎng)?chuàng)建管道文件了,因?yàn)槲覀冊(cè)趕erver端已經(jīng)創(chuàng)建好了int fd = open(FIFO_FILE, O_WRONLY);// 剩下的都是文件操作了if (fd < 0){cerr << "open fifo error" << endl;return 2;}
?// 寫(xiě)入操作string message;int cnt = 1;pid_t id = getpid();while (true){cout << "Please Enter# ";getline(cin, message);message += (",message number: " + to_string(cnt++) + ",[" + to_string(id) + "]");
?// c_str()用于將string對(duì)象轉(zhuǎn)換為 C 風(fēng)格的字符串(即以空字符\0結(jié)尾的字符數(shù)組)int n = write(fd, message.c_str(), message.size());if (n > 0){}}
?close(fd);
?return 0;
}

我們需要先執(zhí)行server編譯后的可執(zhí)行程序,來(lái)創(chuàng)建命名管道,而后它會(huì)阻塞在open那塊,因?yàn)槊艿佬枰獌蓚€(gè)進(jìn)程來(lái)同時(shí)打開(kāi)(我們這里write方?jīng)]有執(zhí)行open時(shí),read方就要在open內(nèi)部阻塞,直到有人把管道文件打開(kāi)了,open才會(huì)返回),所以接下來(lái)我們需要在另一個(gè)終端上執(zhí)行client編譯后的可執(zhí)行程序,就達(dá)到了用命名管道實(shí)現(xiàn)進(jìn)程間通信(從客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送消息)的簡(jiǎn)單效果

image-20250528192036856

image-20250528192053076

當(dāng)我們關(guān)閉寫(xiě)端client時(shí),讀端的number就為0了,然后也跟著退出后刪除管道文件

image-20250528194944842

6.總結(jié)

命名管道和匿名管道的區(qū)別

image-20250527222510087

其他的特性是完全和匿名管道一樣的,只有一點(diǎn)不同,那就是命名管道可以用來(lái)進(jìn)行讓不相關(guān)進(jìn)程進(jìn)行進(jìn)程間通信,命名管道也可以用來(lái)實(shí)現(xiàn)文件的拷貝

http://www.risenshineclean.com/news/58698.html

相關(guān)文章:

  • 做5g網(wǎng)站空間容量要多少錢(qián)長(zhǎng)尾詞在線(xiàn)挖掘
  • 航達(dá)建設(shè)網(wǎng)站正規(guī)的培訓(xùn)機(jī)構(gòu)有哪些
  • 如何生成網(wǎng)站的二維碼輸入關(guān)鍵詞自動(dòng)生成標(biāo)題
  • 凡科做網(wǎng)站html網(wǎng)站模板免費(fèi)
  • 做機(jī)械的專(zhuān)業(yè)外貿(mào)網(wǎng)站有哪些鏈接下載
  • python做網(wǎng)站原理怎么宣傳自己的產(chǎn)品
  • 有做網(wǎng)站設(shè)計(jì)的嗎引擎優(yōu)化seo是什么
  • 怎樣做網(wǎng)站關(guān)鍵詞優(yōu)化網(wǎng)站推廣優(yōu)化外包公司哪家好
  • 真人男女直接做的視頻網(wǎng)站深圳華強(qiáng)北新聞最新消息今天
  • 怎么做網(wǎng)站架構(gòu)網(wǎng)絡(luò)推廣公司收費(fèi)標(biāo)準(zhǔn)
  • 網(wǎng)站首頁(yè)圖片素材長(zhǎng)圖大全搜索引擎哪個(gè)最好用
  • wordpress站群版seo包年服務(wù)
  • 建筑公司電話(huà)號(hào)碼重慶網(wǎng)頁(yè)優(yōu)化seo
  • 網(wǎng)站名稱(chēng)能用商標(biāo)做名稱(chēng)嗎公司網(wǎng)絡(luò)推廣網(wǎng)站
  • 網(wǎng)站的著陸頁(yè)啟信聚客通網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃
  • wordpress 禁用縮略圖電腦優(yōu)化大師官方免費(fèi)下載
  • WordPress太占空間了如何優(yōu)化培訓(xùn)體系
  • 沈陽(yáng)男科醫(yī)院哪家好點(diǎn)兒濟(jì)南seo怎么優(yōu)化
  • 視頻 播放網(wǎng)站怎么做的產(chǎn)品推廣活動(dòng)策劃方案
  • 做網(wǎng)站項(xiàng)目后臺(tái)的seo技術(shù)專(zhuān)員招聘
  • wordpress展示型外貿(mào)網(wǎng)站杭州余杭區(qū)抖音seo質(zhì)量高
  • 蒼南網(wǎng)站設(shè)計(jì)公司河南今日頭條新聞
  • 做網(wǎng)站外包需要提供什么百度搜索關(guān)鍵詞優(yōu)化
  • 網(wǎng)站搭建策劃書(shū)深圳全網(wǎng)推互聯(lián)科技有限公司
  • wordpress選擇表優(yōu)化網(wǎng)站軟文
  • 公司網(wǎng)站制作導(dǎo)航東莞企業(yè)網(wǎng)站推廣
  • 怎么做網(wǎng)站百度貼吧網(wǎng)站seo快速排名優(yōu)化的軟件
  • 深圳羅湖網(wǎng)站設(shè)計(jì)公司價(jià)格seo具體是什么
  • dede怎么做視頻網(wǎng)站網(wǎng)站seo設(shè)計(jì)
  • 網(wǎng)站建設(shè)計(jì)劃建議做網(wǎng)頁(yè)用什么軟件好