linux之管道

管道(PIPE)是linux中一個重要的通信方式,在進程中,我們通過從一個進程中讀取到的數據轉到另一個進程中的寫數據中,這時就要有不同的進程之間共享同一份資源,就是所謂的進程間通信。由于進程的特點是資源獨占,所以我們就借助管道來實現。我們常說的管道多指無名管道,還有一種是命名管道(一次生成多個目標文件[FIFO])。下面分別講解一下:

管道的特點:單向數據通信,有血緣關系的進程通信,生命周期(隨進程的),同步與互斥

管道也是一種文件,它是以p開頭的;

我們可以調用pipe()函數:int pipe(int fileds[2])來在內核中開辟一條緩沖區(即管道)來完成通信。它有一個讀端一個寫端,fileds[0]表示讀端,fileds[1]表示寫端。首先,由父進程創建管道;其次,由父進程創建子進程;最后,父進程關閉fd[0]讀端,子進程關閉fd[1]寫端,這樣就使父進程往管道里寫,子進程往管道里讀,這樣就實現了進程間通信。

然而通過管道實現父子進程之間的通信步驟是什么呢?




代碼實現一下吧:



運行結果如下:


當子進程關閉讀端,父進程關閉寫端時,最后結果會每隔1s打印一個“i am a girl”;

一、對于管道來說我們通常有四種特殊情況需要考慮:

1.如果所有指向管道寫端的文件描述符都關閉了(管道寫端的引用計數等于0),而仍然有進程從管道的讀端讀數據,那

么管道中剩余的數據都被讀取后,再次read會返回0,就像讀到文件末尾一樣。


運行結果:


2.如果有指向管道寫端的文件描述符沒關閉(管道寫端的引用計數大于0),而持有管道寫端的進程也沒有向管道中寫數據,這時有進程從管道讀端讀數據,那么管道中剩余的數 據都被讀取后,再次read會阻塞,直到管道中有數據可讀了才讀取數據并返回。



運行結果:


此時,,會發現當運行完第十個i am a child之后,read端還想讀取時,發生了堵塞。直到關閉寫端后讀端才退出不再讀。

3.如果所有指向管道讀端的文件描述符都關閉了(管道讀端的引用計數等于0),這時有進程向管道的寫端write,那么該進

程會收到信號SIGPIPE,通常會導致進程異常終止。?



運行結果:


此時,在子進程進行寫了10個i am a child時,寫完之后寫端并沒有關閉,當父進程讀完三個i am a child之后,關閉讀端,讀端不再讀,并且sleep了10秒。進程異常中止。

4.如果有指向管道讀端的文件描述符沒關閉(管道讀端的引用計數大于0),而持有管道讀端的進程也沒有從管道中讀數

據,這時有進程向管道寫端寫數據,那么在管道被寫滿時再次write會阻塞,直到管道中有空位置了才寫入數據并返回。



運行結果:


此時,,寫端一直在寫,讀端沒有關閉,但卻不讀取數據,因此會導致write端阻塞,直到異常退出。


二、但是匿名管道只適用于具有血緣關系的進程之間通信。如果兩個進程之間沒有血緣關系的話怎么辦呢?我們把沒有血緣關系的進程之間的通信方式就可以通過命名管道來完成。創建命名管道的系統函數有:mknod和mkfifo。在這里,我們盡可能的使用mkfifo。命名管道也被稱為FIFO文件,它是一種特殊類型的文件,它在文件系統中以文件名的形式存在;下面舉一個兩個不同進程之間進行通信的例子:

server.c為讀端:



client.c為寫端:


將兩個不同的進程之間聯系起來,當client.c寫入數據時,打開另一個終端運行server.c,這樣就會在server.c中顯示出你輸入的字符串,當遇到quit時,進程將結束。

另外,通過命令ulimit -a來看一下管道寫入的最大大小為:


即:512*8 = 4kb;


以上就是管道的基本概念哦。微笑微笑

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

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

相關文章

把student a am i 變成 i am a student(兩種方法)

文章目錄#student a am i 變成 i am a student##方法1&#xff1a;指針#include <stdlib.h> #include <stdio.h> #include <string.h>void fanw(char *l, char *r) {char* left l;char* right r;char temp;while (left < right){temp *left;*left *ri…

關掉占用 某端口的進程

sudo fuser -k 8000/tcp 這樣和端口8000相關的進程就都關了。

linux之多線程(1)

我們之前講了進程&#xff0c;今天我們重新認識另外一個概念---線程。我們首先會想到的是進程和線程有什么區別和聯系&#xff0c;對吧&#xff1f;進程是由程序執行起來&#xff0c;跑在操作系統的&#xff0c;是系統進行資源分配和調度的基本單位。進程具有資源獨占性&#x…

C語言typedef與#define的區別

typedef和#define define 沒有參加編譯&#xff0c;在預處理的時候就被替換掉了。 typedef參加編譯和鏈接。typedef是重命名&#xff0c;可以為枚舉結構體等等重新命名&#xff0c;提高代碼整潔。 一、typedef的用法 C語言中&#xff0c;typedef常用來定義一個標識符及關鍵…

django models模型 內部類 class Meta 簡介

class Meta: #這個屬性是定義當前的模型類是不是一個抽象類。所謂抽象類是不會相應數據庫表的。一般我們用它來歸納一些公共屬性字段&#xff0c;然后繼承它的子類能夠繼承這些字段。abstractTrue #db_table是用于指定自己定義數據庫表名的db_table test#因為Django的管理方法…

阻斷血緣關系以及checkpoint文件清理

spark-sql讀寫同一張表&#xff0c;報錯Cannot overwrite a path that is also being read from 1. 增加checkpoint&#xff0c;設置檢查點阻斷血緣關系 sparkSession.sparkContext.setCheckpointDir("/tmp/spark/job/OrderOnlineSparkJob")val oldOneIdTagSql s&…

linux之睡眠函數(my_sleep)

我們在程序中&#xff0c;很多次用到sleep()函數&#xff0c;讓它睡眠幾秒后再執行該進程。今天呢&#xff0c;我要給大家實現一下sleep函數。 看看代碼哦&#xff1a; 運行結果&#xff1a; 結果中每隔三秒鐘&#xff0c;打印一條語句。實現了sleep(3)的功能。 關于sleep函數…

C語言 防止頭文件被多次引用

comm.h和comm.c是公共模塊。 test1.h和test1.c使用了公共模塊。 test2.h和test2.c使用了了公共模塊。 test.h和test.c使?用了了test1模塊和test2模塊。 這樣最終程序中就會出現兩份comm.h的內容。這樣就造成了了文件內容的重復。 1.方法1 文件開頭加上這一句就ok #prag…

python字符串切片操作

name abcdefghijk name[2:-1] cdefghijname[2:] cdefghijk # 第三個參數是步長 name[2:-1:2] cegi# 字符串反轉 name[::-1] name[-1::-1] kjihgfedcba kjihgfedcba

機器思維。一些讓我眼前一亮的算法。

用人腦相處了計算機處理數據的方式。而不是 人腦處理的方式—>用計算機的語言表達 人腦處理的方式—>計算機處理的方式—>用計算機的語言表達

python 之 __new__ 方法理解

python的new方法 使用場景不同效果也不一樣 一種是指定元類時候&#xff0c; metaclassMyType 類型 這種方式 在解釋器執行到 metaclassCrawlerProxyMetaclass 的時候&#xff0c; __new__方法就開始執行&#xff01; 這里的 __new__方法是用來創建類對象的 class CrawlerProx…

詳解強制類型轉換

今天談談類型轉換的問題吧&#xff0c;之前我們也遇到過類型轉換&#xff0c;比如c語言中這樣的賦值&#xff1a; 顯然&#xff0c;i和j是不同類型的變量&#xff0c;但是卻可以完成賦值&#xff0c;結果是這樣的&#xff1a; 其實它們是做了隱式的類型轉換&#xff0c;相當于&…

面試--輸入一堆隨機數(0-1000),這里面會有重復的數字,把他們去除掉。然后由大到小排列。

1.問題說明 11 10 20 40 32 67 40 20 89 300 400 15 10 15 20//只顯示1次 32 40//只顯示1次 67 89 300 400 正常的算法&#xff1a; 1.遍歷所有數組&#xff0c;去除掉重復的數字 2.使用XX排序法&#xff0c;進行數字的排序。 眼前一亮的機器算法 1.生成1-1000的數組&am…

c++之類型萃取

剛剛我們接觸過模板類&#xff0c;類似于這樣的&#xff1a; 在這個類中&#xff0c;我們如何知道它是什么類型的呢&#xff1f;這里&#xff0c;我們可以在類中加入一個內嵌類型&#xff0c;如&#xff1a; 這樣就可以知道它是用戶自定義的還是本身類型就擁有的&#xff0c;我…

django xadmin出現的問題

1.File “/home/yuanqi/.virtualenvs/djangodev1/lib/python3.5/site-packages/xadmin/sites.py”, line 9, in reload(sys) import importlib importlib.reload(sys)# sys.setdefaultencoding("utf-8")把相應文件改為上述這樣

一道面試題--兩個int(32位)整數m和n的二進制表達中,有多少個位(bit)不同

1.問題說明 十進制4 0100 十進制8 1000二進制不同的 0100 1000有兩位不同 正常的算法 1.兩個數字與1&#xff0c;拿出兩個數字的最后一位&#xff0c;比較是否相同&#xff0c;直到右移32次&#xff0c; for (int i 0; i < 32; i){if ((m & 1) ! (n & 1)){count…

時間復雜度空間復雜度

我們編過不少代碼&#xff0c;起初學習的時候我們習慣性的認為&#xff0c;只要代碼能正確的運行就ok啦~很少考慮代碼的優化帶來的好處。今天說一下影響代碼性能的兩個重要指標--時間復雜度&空間復雜度。 時間復雜度&#xff1a;就是函數&#xff08;指數學中的函數&#…

C語言 函數遞歸例題解析

1.接受一個整形值&#xff08;無符號&#xff09;&#xff0c;把它轉換為 字符并打印它模擬實現strlen()函數。3.求n的階乘4.斐波那契數列總結 1.接受一個整形值&#xff08;無符號&#xff09;&#xff0c;把它轉換為 字符并打印它 void fun(int x) {if (x > 9){fun(x/10)…

xpath 簡單用法小記

1 xpath定位 沒有某個屬性的元素 例如定位沒有class屬性的td tds tr.xpath(.//td[not(class)])