新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux基礎復習(8)進程通信

        linux基礎復習(8)進程通信

        作者: 時間:2016-10-08 來源:網絡 收藏

        數據傳輸:一個進程需要將它的數據發送給另一個進程,發送的數據量在一個字節到幾兆字節之間。

        本文引用地址:http://www.104case.com/article/201610/305812.htm

        共享數據:多個進程想要操作共享數據,一個進程對共享數據的修改,別的進程應該立刻看到。

        通知事件:一個進程需要向另一個或一組進程發送消息,通知它(它們)發生了某種事件(如進程終止時要通知父進程)。

        資源共享:多個進程之間共享同樣的資源。為了作到這一點,需要內核提供鎖和同步機制。

        進程控制:有些進程希望完全控制另一個進程的執行(如Debug進程),此時控制進程希望能夠攔截另一個進程的所有陷入和異常,并能夠及時知道它的狀態改變。

        UNIX 進程間通信(IPC)方式包括管道、FIFO、信號。

        Linux 中使用較多的進程間通信方式主要有以下幾種。

        (1)管道(Pipe)及有名管道(named pipe):管道可用于具有親緣關系進程間的通信,有名管道,除具有管道所具有的功能外,它還允許無親緣關系進程間的通信。

        (2)信號(Signal):信號是在軟件層次上對中斷機制的一種模擬,它是比較復雜的通信方式,用于通知接受進程有某事件發生,一個進程收到一個信號與處理器收到一個中斷請求效果上可以說是一樣的。

        (3)消息隊列:消息隊列是消息的鏈接表,包括Posix 消息隊列systemV 消息隊列。它克服了前兩種通信方式中信息量有限的缺點,具有寫權限的進程可以向消息隊列中按照一定的規則添加新消息;對消息隊列有讀權限的進程則可以從消息隊列中讀取消息。

        (4)共享內存:可以說這是最有用的進程間通信方式。它使得多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數據的更新。這種通信方式需要依靠某種同步機制,如互斥鎖和信號量等。

        (5)信號量:主要作為進程間以及同一進程不同線程之間的同步手段。

        (6)套接字(Socket):這是一種更為一般的進程間通信機制,它可用于不同機器之間的進程間通信,應用非常廣泛。

        [b]管道通信[/b]

        普通的Linux shell都允許重定向,而重定向使用的就是管道。例如:

        ps | grep vsftpd

        管道是單向的、先進先出的、無結構的、固定大小的字節流,它把一個進程的標準輸出和另一個進程的標準輸入連接在一起。寫進程在管道的尾端寫入數據,讀進程在管道的首端讀出數據。數據讀出后將從管道中移走,其它讀進程都不能再讀到這些數據。管道提供了簡單的流控制機制。進程試圖讀空管道時,在有數據寫入管道前,進程將一直阻塞。同樣,管道已經滿時,進程再試圖寫管道,在其它進程從管道中移走數據之前,寫進程將一直阻塞。

        管道主要用于不同進程間通信。

        創建一個簡單的管道,可以使用系統調用pipe( )。它接受一個參數,也就是一個包括兩個整數的數組。如果系統調用成功,此數組將包括管道使用的兩個文件描述符。創建一個管道之后,一般情況下進程將產生一個新的進程。

        系統調用:pipe( );

        原型:int pipe( int fd[2] );

        返回值:如果系統調用成功,返回0。如果系統調用失敗返回- 1:

        errno = EMFILE (沒有空閑的文件描述符)

        EMFILE (系統文件表已滿)

        EFAULT (fd數組無效)

        注意:fd[0] 用于讀取管道,fd[1] 用于寫入管道。

        #i nclude

        #i nclude

        #i nclude

        #i nclude

        int main()

        {

        int pipe_fd[2];

        if(pipe(pipe_fd)0)

        {

        printf(pipe create errorn);

        return -1;

        }

        else

        printf(pipe create successn);

        close(pipe_fd[0]);

        close(pipe_fd[1]);

        }

        管道主要用于不同進程間通信。實際上,通常先創建一個管道,再通過fork函數創建一個子進程。

        可以通過打開兩個管道來創建一個雙向的管道。但需要在子進程中正確地設置文件描述符。

        必須在系統調用fork( )中調用pipe( ),否則子進程將不會繼承文件描述符。

        當使用半雙工管道時,任何關聯的進程都必須共享一個相關的祖先進程。因為管道存在于系統內核之中,所以任何不在創建管道的進程的祖先進程之中的進程都將無法尋址它。而在命名管道中卻不是這樣。

        與linux中文件操作有文件流的標準I/O一樣,管道的操作也支持基于文件流的模式。接口函數如下

        庫函數:popen();

        原型: FILE *popen ( char *command, char *type);

        返回值:如果成功,返回一個新的文件流。如果無法創建進程或者管道,返回NULL。

        管道中數據流的方向是由第二個參數type控制的。此參數可以是r或者w,分別代表讀或寫。但不能同時為讀和寫。在Linux系統下,管道將會以參數type中第一個字符代表的方式打開。所以,如果你在參數type中寫入rw,管道將會以讀的方式打開。

        使用popen()創建的管道必須使用pclose( )關閉。其實,popen/pclose和標準文件輸入/輸出流中的fopen() / fclose()十分相似。

        庫函數: pclose();

        原型: int pclose( FILE *stream );

        返回值: 返回系統調用wait4( )的狀態。

        如果stream無效,或者系統調用wait4( )失敗,則返回 -1。

        注意此庫函數等待管道進程運行結束,然后關閉文件流。

        庫函數pclose( )在使用popen( )創建的進程上執行wait4( )函數。當它返回時,它將破壞管道和文件系統。

        #i nclude

        #i nclude

        #i nclude

        #i nclude

        #define BUFSIZE 1024

        int main()

        {

        FILE *fp;

        char *cmd = ps -ef;

        char buf[BUFSIZE];

        buf[BUFSIZE] = '

        主站蜘蛛池模板: 璧山县| 页游| 博罗县| 同仁县| 定陶县| 珲春市| 昭觉县| 平遥县| 卢湾区| 柘荣县| 桂东县| 荣昌县| 无棣县| 临邑县| 海南省| 信丰县| 九龙坡区| 昌乐县| 建昌县| 三江| 得荣县| 桐柏县| 溧水县| 龙里县| 福建省| 榆社县| 广水市| 黔南| 沂南县| 镇沅| 石狮市| 青川县| 保定市| 湖北省| 酒泉市| 英吉沙县| 靖江市| 济南市| 巴南区| 南皮县| 东台市|