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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

使用系统调用pipe建立一条管道线_【Linux系统】Linux进程间通信

發布時間:2023/12/19 linux 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用系统调用pipe建立一条管道线_【Linux系统】Linux进程间通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:Vamei

出處:http://www.cnblogs.com/vamei

我們在Linux信號基礎中已經說明,信號可以看作一種粗糙的進程間通信(IPC, interprocess communication)的方式,用以向進程封閉的內存空間傳遞信息。為了讓進程間傳遞更多的信息量,我們需要其他的進程間通信方式。這些進程間通信方式可以分為兩種:

管道機制:可以使用管道將一個進程的輸出和另一個進程的輸入連接起來,從而利用文件操作API來管理進程間通信。在shell中,我們經常利用管道將多個進程連接在一起,從而讓各個進程協作,實現復雜的功能。

傳統IPC:主要是指消息隊列(message queue),信號量(semaphore),共享內存(shared memory)。這些IPC的特點是允許多進程之間共享資源,這與多線程共享heap和global data相類似。由于多進程任務具有并發性 (每個進程包含一個進程,多個進程的話就有多個線程),所以在共享資源的時候也必須解決同步的問題 (參考Linux多線程與同步)。?

管道與FIFO文件一個原始的IPC方式是所有的進程通過一個文件交流。比如我在紙(文件)上寫下我的名字和年紀。另一個人讀這張紙,會知道我的名字和年紀。他也可以在同一張紙上寫下他的信息,而當我讀這張紙的話,同樣也可以知道別人的信息。但是,由于硬盤讀寫比較慢,所以這個方式效率很低。那么,我們是否可以將這張紙放入內存中以提高讀寫速度呢?

在Linux文本流中,我們已經講解了如何在shell中使用管道連接多個進程。同樣,許多編程語言中,也有一些命令用以實現類似的機制,比如在Python子進程中使用Popen和PIPE,在C語言中也有popen庫函數來實現管道 (shell中的管道就是根據此編寫的)。

管道是由內核管理的一個緩沖區(buffer),相當于我們放入內存中的一個紙條。管道的一端連接一個進程的輸出。這個進程會向管道中放入信息。管道的另一端連接一個進程的輸入,這個進程取出被放入管道的信息。一個緩沖區不需要很大,它被設計成為環形的數據結構,以便管道可以被循環利用。

當管道中沒有信息的話,從管道中讀取的進程會等待,直到另一端的進程放入信息。當管道被放滿信息的時候,嘗試放入信息的進程會等待,直到另一端的進程取出信息。當兩個進程都終結的時候,管道也自動消失。

從原理上,管道利用fork機制建立(參考Linux進程基礎和Linux從程序到進程),從而讓兩個進程可以連接到同一個PIPE上。最開始的時候,上面的兩個箭頭都連接在同一個進程Process 1上(連接在Process 1上的兩個箭頭)。當fork復制進程的時候,會將這兩個連接也復制到新的進程(Process 2)。隨后,每個進程關閉自己不需要的一個連接 (兩個黑色的箭頭被關閉; Process 1關閉從PIPE來的輸入連接,Process 2關閉輸出到PIPE的連接),這樣,剩下的紅色連接就構成了如上圖的PIPE。

由于基于fork機制,所以管道只能用于父進程和子進程之間,或者擁有相同祖先的兩個子進程之間 (有親緣關系的進程之間)。為了解決這一問題,Linux提供了FIFO方式連接進程。FIFO又叫做命名管道(named PIPE)。

FIFO (First in, First out)為一種特殊的文件類型,它在文件系統中有對應的路徑。當一個進程以讀(r)的方式打開該文件,而另一個進程以寫(w)的方式打開該文件,那么內核就會在這兩個進程之間建立管道,所以FIFO實際上也由內核管理,不與硬盤打交道。之所以叫FIFO,是因為管道本質上是一個先進先出的隊列數據結構,最早放入的數據被最先讀出來(好像是傳送帶,一頭放貨,一頭取貨),從而保證信息交流的順序。FIFO只是借用了文件系統(file system, 參考Linux文件管理背景知識)來為管道命名。寫模式的進程向FIFO文件中寫入,而讀模式的進程從FIFO文件中讀出。當刪除FIFO文件時,管道連接也隨之消失。FIFO的好處在于我們可以通過文件的路徑來識別管道,從而讓沒有親緣關系的進程之間建立連接。傳統IPC這幾種傳統IPC實際上有很悠久的歷史,所以其實現方式也并不完善 (比如說我們需要某個進程負責刪除建立的IPC)。一個共同的特征是它們并不使用文件操作的API。對于任何一種IPC來說,你都可以建立多個連接,并使用鍵值(key)作為識別的方式。我們可以在一個進程中中通過鍵值來使用的想要那一個連接 (比如多個消息隊列,而我們選擇使用其中的一個)。鍵值可以通過某種IPC方式在進程間傳遞(比如說我們上面說的PIPE,FIFO或者寫入文件),也可以在編程的時候內置于程序中。在幾個進程共享鍵值的情況下,這些傳統IPC非常類似于多線程共享資源的方式(參看Linux多線程與同步):

#:semaphore與mutex類似,用于處理同步問題。我們說mutex像是一個只能容納一個人的洗手間,那么semaphore就像是一個能容納N個人的洗手間。其實從意義上來說,semaphore就是一個計數鎖,它允許被N個進程獲得。當有更多的進程嘗試獲得semaphore的時候,就必須等待有前面的進程釋放鎖。當N等于1的時候,semaphore與mutex實現的功能就完全相同,一個semaphore會一直存在在內核中,直到某個進程刪除它。

#:共享內存與多線程共享global data和heap類似。一個進程可以將自己內存空間中的一部分拿出來,允許其它進程讀寫。當使用共享內存的時候,我們要注意同步的問題。我們可以使用semaphore同步,也可以在共享內存中建立mutex或其它的線程同步變量來同步。由于共享內存允許多個進程直接對同一個內存區域直接操作,所以它是效率最高的IPC方式。

消息隊列(message queue)與PIPE相類似。它也是建立一個隊列,先放入隊列的消息被最先取出。不同的是,消息隊列允許多個進程放入消息,也允許多個進程取出消息。每個消息可以帶有一個整數識別符(message_type)。你可以通過識別符對消息分類 (極端的情況是將每個消息設置一個不同的識別符)。

某個進程從隊列中取出消息的時候,可以按照先進先出的順序取出,也可以只取出符合某個識別符的消息(有多個這樣的消息時,同樣按照先進先出的順序取出)。消息隊列與PIPE的另一個不同在于它并不使用文件API。最后,一個隊列不會自動消失,它會一直存在于內核中,直到某個進程刪除該隊列。

多進程協作可以幫助我們充分利用多核和網絡時代帶來的優勢。多進程可以有效解決計算瓶頸的問題。互聯網通信實際上也是一個進程間通信的問題,只不過這多個進程分布于不同的電腦上。網絡連接是通過socket實現的。由于socket內容龐大,所以我們不在這里深入。一個小小的注解是,socket也可以用于計算機內部進程間的通信。

總結

以上是生活随笔為你收集整理的使用系统调用pipe建立一条管道线_【Linux系统】Linux进程间通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。