欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux管道揭秘之匿名管道連接進(jìn)程世界的方法

 更新時間:2024年11月09日 10:09:30   作者:Yui_  
文章介紹了Linux中的管道(Pipe)概念,包括其定義、作用、類型、工作原理以及如何在父子進(jìn)程間使用,匿名管道是進(jìn)程間通信的一種機(jī)制,通過pipe()系統(tǒng)調(diào)用創(chuàng)建,具有讀端和寫端文件描述符,文章詳細(xì)解釋了匿名管道的創(chuàng)建、使用流程、4種情況和5種特性

1.什么是管道 ?

管道(Pipe)是一種常見的進(jìn)程間通信(IPC,Inter-Process Communication)機(jī)制,在 Unix/Linux 系統(tǒng)中尤其重要。它允許一個進(jìn)程的輸出直接作為另一個進(jìn)程的輸入,而不需要使用中間文件。管道通常用于將多個命令連接起來,讓它們像流水線一樣處理數(shù)據(jù)。
管道在 Unix/Linux 系統(tǒng)中提供了一種簡便的機(jī)制,允許數(shù)據(jù)在不同進(jìn)程之間傳遞。它提供了一個緩沖區(qū),數(shù)據(jù)寫入管道的一端(寫端),然后可以從另一端(讀端)讀取。管道的本質(zhì)是一種半雙工的通信機(jī)制,即數(shù)據(jù)只能沿一個方向流動。
提問:有沒有一些直觀的管道的利用?
當(dāng)然。其實早在Linux的指令學(xué)習(xí)中,我們就已經(jīng)接觸到了管道。就是這個符號|。

ubuntu@VM-20-9-ubuntu:~/pipeTest$ ls -l
total 24
-rwxrwxr-x 1 ubuntu ubuntu 16576 Nov  5 11:41 a.out
-rw-rw-r-- 1 ubuntu ubuntu  1285 Nov  5 11:40 pipeTest1.c
ubuntu@VM-20-9-ubuntu:~/pipeTest$ ls -l|grep "pipeTest1.c"
-rw-rw-r-- 1 ubuntu ubuntu  1285 Nov  5 11:40 pipeTest1.c
ubuntu@VM-20-9-ubuntu:~/pipeTest$ 

這就是一個管道的簡單使用,我們都知道,在大部分Linux的指令都是一個可執(zhí)行文件,運行起來就是一個進(jìn)程。ls -l的作用就是顯示當(dāng)前目錄文件的信息,現(xiàn)在我們通過|將這個顯示的信息通過管道傳遞給grep,不就實現(xiàn)了兩個進(jìn)程間的相互通信了嘛。這就是管道的核心作用:實現(xiàn)進(jìn)程間的通信,高效傳遞數(shù)據(jù),避免了使用臨時文件的麻煩.

2. 管道的類型

管道存在兩種類型:

  • 匿名管道,用于父子進(jìn)程或者兄弟進(jìn)程間的數(shù)據(jù)傳遞,沒有名字,僅限具有親緣關(guān)系的進(jìn)程。
  • 命名進(jìn)程,具有文件名,可以在不相干的進(jìn)程間使用。

2.1 匿名管道

匿名管道通過pipe()創(chuàng)建。

2.1.1 介紹pipe()

#include <unistd.h>
int pipe(int pipefd[2]);

pipefd:是一個數(shù)組,它包含兩個元素,分別是管道的讀端和寫端的文件描述符。

  • pipefd[0]:讀端(用于讀取數(shù)據(jù))。
  • pipefd[1]:寫端(用于寫入數(shù)據(jù))。
  • pipe()創(chuàng)建一個管道,并將兩個文件描述符存儲在pipefd數(shù)組中。
  • 管道的數(shù)據(jù)流是單向的:數(shù)據(jù)從寫端流向讀端。
  • 關(guān)于返回值
  • 成功:返回0.
  • 失?。悍祷?1.

使用pepe()的基本流程:

  • 創(chuàng)建管道:調(diào)用pipe()函數(shù)。
  • 使用fork()創(chuàng)建一個子進(jìn)程。
  • 在父進(jìn)程關(guān)閉寫端,使用讀端讀取數(shù)據(jù)。
  • 在子進(jìn)程中關(guān)閉讀端,使用寫端將數(shù)據(jù)傳輸給父進(jìn)程。

2.1.2 pipe()簡單示例:父子進(jìn)程通過管道通信

//本代碼用來測試子進(jìn)程提供匿名管道將信息傳遞給父進(jìn)程 24/11/5
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SIZE 1024
void writer(int wfd)
{
    char buf[SIZE];
    const char* str = "hello father,i am child";
    int count = 1;
    pid_t id = getpid();
    while(true)
    {
        //格式化輸入
        snprintf(buf,sizeof(buf)-1,"message:%s,pid:%d,times:%d",str,id,count);
        write(wfd,buf,strlen(buf));
        count+=1;
        sleep(1);
    }
}
void reader(int rfd)
{
    char buf[SIZE];
    while(true)
    {
        ssize_t n = read(rfd,buf,sizeof(buf)-1);
        if(n == -1)
        {
            perror("read");
            return;
        }
        printf("%s\n",buf);
    }
}
int main()
{
    //文件標(biāo)識符
    int fd[2];
    if(pipe(fd) < 0)
    {
        //error
        perror("pipe error");
        return 1;
    }
    pid_t id = fork();
    if(id<0)
    {
        perror("fork error");
        return 1;
    }
    else if(id == 0)
    {
        //child
        //關(guān)閉讀端
        close(fd[0]);
        writer(fd[1]);
        exit(1);
    }
    //father
    close(fd[1]);
    reader(fd[0]);
    wait(NULL);
    return 0;
}

運行結(jié)果:

運行結(jié)果

如此我們我們便實現(xiàn)了父子間的管道通信。
pipe() 是一個非常重要的系統(tǒng)調(diào)用,它為進(jìn)程間通信提供了一個簡單而高效的機(jī)制。通過管道,多個進(jìn)程可以協(xié)作完成任務(wù),并且避免了中間文件的使用。在父子進(jìn)程之間的通信,或在處理大量數(shù)據(jù)時,管道通常是最常用的 IPC 方式之一。

2.1.3 管道的4種情況與5種特性

4種情況:

  • 管道內(nèi)部沒有數(shù)據(jù)時且子進(jìn)程不關(guān)閉自己的寫端文件fd,讀端(父)就會堵塞等待,直到pipe有數(shù)據(jù),
  • 管道內(nèi)部被寫滿且父進(jìn)程(讀端)不關(guān)閉自己的fd,寫端寫滿后,就會堵塞等待。
  • 對于寫端而言:不寫了且關(guān)閉了pipe,讀端會將pipe中的數(shù)據(jù)讀完,最后就會讀到返回值為0,表示讀結(jié)束,類似讀到了文件的結(jié)尾。
  • 讀端不讀且關(guān)閉,寫再寫,OS會直接終結(jié)寫入的進(jìn)程(子進(jìn)程)通過信號13)SIGPIPE來殺死進(jìn)程。
  • 5種特性:
  • 自帶同步機(jī)制。
  • 血緣關(guān)系進(jìn)行通信,常見于父子進(jìn)程。
  • pipe是面向字節(jié)流的。
  • 父子進(jìn)程退出,管道自動釋放,文件的生命周期是跟隨進(jìn)程的。
  • 管道只能單向通信,半雙工的一種特殊情況。

2.1.4 匿名管道原理

通過父子進(jìn)程繼承關(guān)系,再將文件描述符關(guān)閉,實現(xiàn)一端寫,一端讀就是匿名管道.
創(chuàng)建匿名管道的步驟:

父進(jìn)程以讀寫的方式打開,文件。父進(jìn)程fork創(chuàng)建子進(jìn)程,子進(jìn)程會拷貝一份PCB結(jié)構(gòu),PCB中會包含files_struct結(jié)構(gòu),files_struct中有一個指向struct file(文件)的指針數(shù)組,而文件描述符就是這個數(shù)組的下標(biāo)。
拷貝完成后,子進(jìn)程也就存在了指向struct file的對應(yīng)文件描述符。
又因為,struct file是獨屬于的文件的,和進(jìn)程沒有關(guān)系,也就不用拷貝,也就是說此時父子進(jìn)程同時指向了一塊公共區(qū)域struct file(不同進(jìn)程看見同一份資源)。
write是系統(tǒng)調(diào)用接口,會將數(shù)據(jù)放在內(nèi)核緩沖區(qū),底層會定期刷新緩沖區(qū)將內(nèi)容寫入磁盤。
匿名管道是一個半雙工的通信機(jī)制,也就是說,數(shù)據(jù)只能沿一個方向流動,為了實現(xiàn)半雙工的通信方式,父子進(jìn)程需要關(guān)閉各種不需要的文件描述符。

2.1.5 用fork來共享管道的原理

使用fork后

2.1.6 站在文件描述符角度-深度理解管道

0 1 2 分別為 標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯誤。

2.1.7 站在內(nèi)核角度-管道的本質(zhì)

Linux下一切皆文件.
所以我們也應(yīng)該用看待文件的眼觀,去理解管道。
我們可以將管道(Pipe)理解為一種特殊類型的文件。實際上,管道確實是由操作系統(tǒng)內(nèi)部的內(nèi)存緩沖區(qū)實現(xiàn)的,它通過文件描述符來進(jìn)行訪問,就像其他普通文件一樣。通過這種類比,我們可以從文件的角度理解管道。

3. 匿名管道總結(jié)

通過匿名管道,進(jìn)程可以輕松地進(jìn)行數(shù)據(jù)交換,而不需要借助臨時文件或其他外部資源。盡管管道有一些局限性(如單向傳輸和緩沖區(qū)限制),它仍然是許多進(jìn)程間通信場景中常見的選擇。
注意:管道是半雙工的,數(shù)據(jù)只能向一個方向流動,需要雙方通信時,可以建立兩個管道。

到此這篇關(guān)于Linux管道揭秘:匿名管道如何連接進(jìn)程世界的文章就介紹到這了,更多相關(guān)Linux匿名管道內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)字符格式相互轉(zhuǎn)換的示例代碼

    C++實現(xiàn)字符格式相互轉(zhuǎn)換的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++中實現(xiàn)字符格式相互轉(zhuǎn)換的方法,主要有UTF8與string互轉(zhuǎn)、wstring與string互轉(zhuǎn),感興趣的小伙伴可以了解一下
    2022-11-11
  • C語言編程簡單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解

    C語言編程簡單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解

    這篇文章主要為大家介紹了C語言編程中非常簡單卻又非常重要的數(shù)據(jù)結(jié)構(gòu)順序表的全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • C++實現(xiàn)職工管理系統(tǒng)

    C++實現(xiàn)職工管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)職工管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++中rapidjson將map轉(zhuǎn)為json的方法

    C++中rapidjson將map轉(zhuǎn)為json的方法

    今天小編就為大家分享一篇關(guān)于C++中rapidjson將map轉(zhuǎn)為json的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • C++面試題之結(jié)構(gòu)體內(nèi)存對齊計算問題總結(jié)大全

    C++面試題之結(jié)構(gòu)體內(nèi)存對齊計算問題總結(jié)大全

    這篇文章主要給大家總結(jié)了關(guān)于C++面試題中結(jié)構(gòu)體內(nèi)存對齊計算問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),通過這些介紹的內(nèi)容對大家在面試C++工作的時候,會有一定的參考幫助,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • C++ static的使用方法及不同含義講解

    C++ static的使用方法及不同含義講解

    在 C++ 里,static 是一個用途廣泛的關(guān)鍵字,在不同場景下有不同含義,下面通過實例代碼介紹C++ static的使用方法及不同含義講解,感興趣的朋友一起看看吧
    2025-04-04
  • OpenCV使用BSM統(tǒng)計視頻中移動的對象

    OpenCV使用BSM統(tǒng)計視頻中移動的對象

    這篇文章主要為大家詳細(xì)介紹了OpenCV如何使用BackgroundSubstractor(BSM)實現(xiàn)視頻中移動對象統(tǒng)計功能,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-02-02
  • C++的matlab接口轉(zhuǎn)換方法詳解

    C++的matlab接口轉(zhuǎn)換方法詳解

    這篇文章主要為大家詳細(xì)介紹了C++的matlab接口轉(zhuǎn)換方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 深入理解C++ 空類大小

    深入理解C++ 空類大小

    本文主要介紹了C++ 空類大小,規(guī)定空類大小為1字節(jié),主要是為了保證對象的唯一性和可區(qū)分性,滿足數(shù)組元素地址連續(xù)的要求,下面就來了解一下
    2025-01-01
  • C++如何調(diào)用簡單的python程序

    C++如何調(diào)用簡單的python程序

    這篇文章主要介紹了C++如何調(diào)用簡單的python程序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論