日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux系统编程-管道入门

發(fā)布時(shí)間:2023/12/20 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统编程-管道入门 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

晚上好,繼續(xù)記錄我的學(xué)習(xí)心得。

當(dāng)你厭倦了自己的目標(biāo)時(shí),怎樣繼續(xù)保持專注?

誤區(qū):
成功人士說(shuō)的都是自己如何“滿懷熱情”去努力實(shí)現(xiàn)他們的目標(biāo)。不管是在商業(yè)、體育還是藝術(shù)界,我們聽(tīng)到的都是“一切都?xì)w結(jié)于激情”或者“你必須真的渴望得到它”之類的說(shuō)法。

這讓我們認(rèn)為成功人士會(huì)有無(wú)限的激情,如果我們感到自己激情消退了,仿佛說(shuō)明了我們不如他們,這讓人很沮喪。

事實(shí)是:
他們沒(méi)把話說(shuō)完整。成功人士也會(huì)和普通人一樣感到激情消退,這是任何人都無(wú)法逃脫的。熟能生巧。你練習(xí)的次數(shù)越多,它就變得越無(wú)聊,越像是機(jī)械地重復(fù)。

成功的最大威脅不是失敗,而是倦怠
我們厭倦了好習(xí)慣,因?yàn)樗鼈儾辉僮屛覀冮_心。就好像寫作一樣,長(zhǎng)期來(lái)看會(huì)給我?guī)?lái)好的結(jié)果,但是總會(huì)有那么幾天我也會(huì)感覺(jué)寫作是枯燥的。

成功人士更強(qiáng)大的地方在于:
盡管感到枯燥乏味,他們?nèi)韵朕k法堅(jiān)持下去。

對(duì)抗枯燥感的小技巧:
在開始做自己不不想做的事情時(shí): 先一邊聽(tīng)音樂(lè)一邊干,15分鐘后再摘下耳機(jī)。必須控制時(shí)間,因?yàn)槁?tīng)得越多,音樂(lè)給你帶來(lái)的滿足感就會(huì)越少。

以下是正文,先明確一下正文的目的:

  • 舉例說(shuō)明 Linux 下父子進(jìn)程如何使用管道進(jìn)行通訊。

目錄:

一、概述-?1.?IPC?工具分類-?2.?什么是管道-?3.?管道的?2?個(gè)局限性-?4.?管道是最常用的?IPC-?5.?使用?pipe()?創(chuàng)建管道二、一個(gè)簡(jiǎn)單的例子?(simple_pipe.c)-?1.?代碼分析-?2.?相關(guān)要點(diǎn)三、參考書籍四、歡迎加入我的微信群

一、概述

1. IPC 工具分類

  • 通信類 (communication):這類工具關(guān)注進(jìn)程之間的數(shù)據(jù)交換。

  • 同步類 (synchronization):這類工具關(guān)注進(jìn)程和線程操作之間的同步。

  • 信號(hào)類 (signal):盡管信號(hào)的主要作用并不在此,但在特定場(chǎng)景下仍然可以將它作為一種同步技術(shù)。更罕見(jiàn)的是信號(hào)還可以作為一種通信技術(shù):信號(hào)編號(hào)本身是一種形式的信息,并且可以在實(shí)時(shí)信號(hào)上綁定數(shù)據(jù)。

2. 什么是管道

當(dāng)從一個(gè)進(jìn)程連接數(shù)據(jù)流到另一個(gè)進(jìn)程時(shí),我們使用術(shù)語(yǔ)管道 (pipe),也叫無(wú)名管道 (unnamed pipe)。通常是把一個(gè)進(jìn)程的輸出通過(guò)管道連接到另一個(gè)進(jìn)程的輸入。

管道是 UNIX 系統(tǒng)最古老的 IPC ,所有 UNIX 系統(tǒng)都提供這種通信機(jī)制。

3. 管道的 2 個(gè)局限性

  • 歷史上,它是半雙工的 (即數(shù)據(jù)只能在一個(gè)方向上流動(dòng))。現(xiàn)在,某些系統(tǒng)提供全雙工管道,但是為了可移植性,我們不應(yīng)預(yù)先假定系統(tǒng)支持全雙工管道。

  • 管道只能在具有公共祖先的兩個(gè)進(jìn)程之間使用。通常,一個(gè)管道由一個(gè)進(jìn)程創(chuàng)建,在進(jìn)程調(diào)用 fork 之后,這個(gè)管道就能在父進(jìn)程和子進(jìn)程之間使用了。

4. 盡管有這 2 個(gè)局限性,半雙工管道仍是最常用的 IPC

每當(dāng)在管道中鍵入一個(gè)命令序列,讓 shell 執(zhí)行時(shí),shell 都會(huì)為每一條命令單獨(dú)創(chuàng)建一個(gè)進(jìn)程,然后用管道將前一條命令進(jìn)程的標(biāo)準(zhǔn)輸出與后一條命令的標(biāo)準(zhǔn)輸入相連接。shell 負(fù)責(zé)安排兩個(gè)命令的標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出:

  • cmd1 的標(biāo)準(zhǔn)輸入來(lái)自終端鍵盤;

  • cmd1 的標(biāo)準(zhǔn)輸出傳遞給 cmd2,作為它的標(biāo)準(zhǔn)輸入;

  • cmd2 的標(biāo)準(zhǔn)輸出連接到終端屏幕;

shell 所做的工作實(shí)際上是對(duì)標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出流進(jìn)行了重新連接,使數(shù)據(jù)流從鍵盤輸入通過(guò)兩個(gè)命令最終輸出到屏幕上。

以 "$ ls | wc -l" 為例:

5. 使用 pipe() 創(chuàng)建管道

$?man?2?pipe NAMEpipe,?pipe2?-?create?pipe SYNOPSIS#include?<unistd.h>int?pipe(int?filedes[2]);

成功的 pipe() 調(diào)用會(huì)在數(shù)組 filedes 中返回兩個(gè)打開的文件描述符:一個(gè)表示管道的讀取端 (filedes[0]),另一個(gè)表示管道的寫入端 (filedes[1])。

與所有文件描述符一樣,可以使用 read() 和 write() 在管道上執(zhí)行 I/O 操作。一旦向管道的寫入端寫入數(shù)據(jù)之后立即就能從管道的讀取端讀取數(shù)據(jù)。

二、一個(gè)簡(jiǎn)單的例子 (simple_pipe.c)

1. 代碼分析

下面的程序演示了如何將管道用于父進(jìn)程和子進(jìn)程之間的通信:

int?main(int?argc,?char?*argv[]) {int?pfd[2];char?buf[BUF_SIZE];ssize_t?numRead;if?(argc?!=?2?||?strcmp(argv[1],?"--help")?==?0)usageErr("%s?string\n",?argv[0]);if?(pipe(pfd)?==?-1)????/*?Create?the?pipe?*/errExit("pipe");switch?(fork())?{case?-1:errExit("fork");case?0:?????????????/*?Child??-?reads?from?pipe?*/if?(close(pfd[1])?==?-1)????????????/*?Write?end?is?unused?*/errExit("close?-?child");for?(;;)?{??????????????/*?Read?data?from?pipe,?echo?on?stdout?*/numRead?=?read(pfd[0],?buf,?BUF_SIZE);if?(numRead?==?-1)errExit("read");if?(numRead?==?0)break;??????????????????????/*?End-of-file?*/if?(write(STDOUT_FILENO,?buf,?numRead)?!=?numRead)fatal("child?-?partial/failed?write");}//?cleanup...default:????????????/*?Parent?-?writes?to?pipe?*/if?(close(pfd[0])?==?-1)????????????/*?Read?end?is?unused?*/errExit("close?-?parent");if?(write(pfd[1],?argv[1],?strlen(argv[1]))?!=?strlen(argv[1]))fatal("parent?-?partial/failed?write");if?(close(pfd[1])?==?-1)????????????/*?Child?will?see?EOF?*/errExit("close");wait(NULL);?????????????????????????/*?Wait?for?child?to?finish?*/exit(EXIT_SUCCESS);} }

運(yùn)行效果:

$?./simple_pipe?'msg?from?parent' msg?from?parent

單個(gè)進(jìn)程中的管道幾乎沒(méi)有任何用處。一般來(lái)講都是使用管道讓兩個(gè)進(jìn)程進(jìn)行通信。為了讓兩個(gè)進(jìn)程通過(guò)管道進(jìn)行連接,在調(diào)用完 pipe() 之后可以調(diào)用 fork(),子進(jìn)程會(huì)繼承父進(jìn)程的文件描述符的副本:

雖然父進(jìn)程和子進(jìn)程都可以從管道中讀取和寫入數(shù)據(jù),但一般不這么使用管道。通常,在 fork() 之后,其中一個(gè)進(jìn)程應(yīng)該立即關(guān)閉管道的寫入端的描述符,另一個(gè)則應(yīng)該關(guān)閉讀取端的描述符。在上面的例子中,父進(jìn)程向子進(jìn)程傳輸數(shù)據(jù),所以它關(guān)閉了管道的讀取端的描述符 filedes[0],而子進(jìn)程則關(guān)閉管道的寫入端的描述符 filedes[1]:


2. 相關(guān)要點(diǎn)

  • 父子進(jìn)程從同一個(gè)管道中讀取和寫入數(shù)據(jù)這種做法不好的原因是:

    • 如果兩個(gè)進(jìn)程同時(shí)試圖從管道中讀取數(shù)據(jù),那么就無(wú)法確定哪個(gè)進(jìn)程會(huì)首先讀取成功——兩個(gè)進(jìn)程競(jìng)爭(zhēng)數(shù)據(jù)了,即會(huì)產(chǎn)生競(jìng)爭(zhēng)。

    • 使用管道進(jìn)行雙向通信更加簡(jiǎn)單的方法是:創(chuàng)建兩個(gè)管道,在兩個(gè)進(jìn)程之間發(fā)送數(shù)據(jù)的兩個(gè)方向上各使用一個(gè)。

    • 管道可以用于任意兩個(gè)(或更多)相關(guān)進(jìn)程之間的通信,只要在創(chuàng)建子進(jìn)程的系列 fork() 調(diào)用之前通過(guò)一個(gè)共同的祖先進(jìn)程創(chuàng)建管道即可。

    • 關(guān)閉未使用管道文件描述符對(duì)于正確使用管道非常重要的:

      • 當(dāng) read 一個(gè)寫入端 (write end) 已被關(guān)閉的管道時(shí),在所有數(shù)據(jù)都被讀取后,read 會(huì)返回 0,這時(shí)讀取進(jìn)程就知道文件已結(jié)束了。

      • 如果讀取進(jìn)程沒(méi)有關(guān)閉管道的寫入端,那么在其他進(jìn)程關(guān)閉了寫入描述符之后,讀取進(jìn)程也不會(huì)看到文件結(jié)束,即使它讀完了管道中的所有數(shù)據(jù)。

      • 當(dāng) write 一個(gè)讀取端已被關(guān)閉的管道,內(nèi)核會(huì)向?qū)懭脒M(jìn)程發(fā)送一個(gè)SIGPIPE 信號(hào)。在默認(rèn)情況下,這個(gè)信號(hào)會(huì)殺死進(jìn)程。但進(jìn)程可以捕獲或忽略該信號(hào),這時(shí)管道上的 write() 操作因 EPIPE 錯(cuò)誤而失敗。收到SIGPIPE 信號(hào) 和獲得 EPIPE 錯(cuò)誤對(duì)于可以起到標(biāo)示管道狀態(tài)的作用。

    • 在寫管道時(shí),常量 PIPE_BUF 規(guī)定了內(nèi)核的管道緩沖區(qū)大小。

      • 如果對(duì)管道調(diào)用 write(),而且要求寫的字節(jié)數(shù)小于等于 PIPE_BUF,則此操作不會(huì)與其他進(jìn)程對(duì)同一管道的 write 操作交叉進(jìn)行。

      • 如果有多個(gè)進(jìn)程同時(shí)寫一個(gè)管道,且要求寫入的字節(jié)數(shù)超過(guò) PIPE_BUF,則所寫的數(shù)據(jù)可能會(huì)與其他進(jìn)程所寫的數(shù)據(jù)交錯(cuò)在一起。

      三、相關(guān)參考

      • 《UNIX 環(huán)境高級(jí)編程 - 15.2 管道》

      • 《Linux / UNIX 系統(tǒng)編程手冊(cè) - 44.管道和FIFO》

      • 《Linux 程序設(shè)計(jì) - 13.進(jìn)程間通信:管道》

      • 《UNIX-Linux編程實(shí)踐教程 - 10.I/O 重定向和管道》

      更多值得學(xué)習(xí)的知識(shí)點(diǎn):

      • 將管道作為一種進(jìn)程同步的方法;

      • 使用管道連接過(guò)濾器;

      • 通過(guò)管道與 shell 命令進(jìn)行通信:popen();

      • 管道和 stdio 緩沖;

      • 命名管道:FIFO; ...

      鑒于大多數(shù)人的注意力無(wú)法在一篇文章里上集中太久,更多的內(nèi)容請(qǐng)大家自行去閱讀吧,不是自己理解到的東西是消化不了的。有機(jī)會(huì)的話我會(huì)把更多的讀書心得放在后面的文章。

      你和我各有一個(gè)蘋果,如果我們交換蘋果的話,我們還是只有一個(gè)蘋果。但當(dāng)你和我各有一個(gè)想法,我們交換想法的話,我們就都有兩個(gè)想法了。如果你也對(duì) 嵌入式系統(tǒng)和開源軟件 感興趣,并且想和更多人互相交流學(xué)習(xí)的話,請(qǐng)關(guān)注我的公眾號(hào):嵌入式 Hacker,一起來(lái)學(xué)習(xí)吧,無(wú)論是 關(guān)注或轉(zhuǎn)發(fā) , 還是賞賜,都是對(duì)作者莫大的支持,感謝 各位的大拇指「在看」 ,,祝工作順利,家庭和睦~

      ? 推薦閱讀:

      ??專輯|Linux文章匯總

      ??專輯|程序人生

      ??專輯|C語(yǔ)言

      嵌入式Linux

      微信掃描二維碼,關(guān)注我的公眾號(hào)

    總結(jié)

    以上是生活随笔為你收集整理的Linux系统编程-管道入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。