當前位置:
首頁 > 知識 > Linux講解 進程間通信 命名管道

Linux講解 進程間通信 命名管道

上次我們講了進程間通過管道通信的方式,上次所說的管道也叫做匿名管道,匿名管道創建了一塊緩衝區供進程來使用,但是這塊緩衝區是沒有名字的,因此除了具有親緣關係的進程之外其他進程都找不到這塊緩衝區。 今天我們要介紹的是命名管道,命名管道實際上是一種特殊文件,在同一台計算機的不同進程之間或在跨越一個網路的不同計算機的不同進程之間,支持可靠的、單向或雙向的數據通信。在創建這個命名管道的時候給他起一個名字,任何進程都可以通過這個文件名來訪問這個FIFO文件。因為匿名管道是我們內存中的特殊文件,但是命名管道是我們磁碟上的文件,命名管道和匿名管道只是他們的創建方式和打開方式,其他步驟都是相同的。 這裡我們通過一個程序來實現一下我們的命名管道,命名管道本質就是一個特殊的文件,所以我們在創建這個文件的時候,我們可以選擇提前創建好,在進程中直接使用同樣我們也可以在程序內創建一個我們的FIFO文件。 我們可以通過mkfifo filename來創建我們的FIFO文件創建成功之後發現我們的test.fifo是特殊的黃色。 並且能看到一種新的文件類型p也就是我們的管道文件。 為了驗證我們的fifo文件可以在不同進程間使用我們用兩個程序,一個專門讀一個專門寫。 //我們首先實現向管道文件中寫入數據的程序 #include #include #include #include #include #include int main() { umask(0); if(mkfifo("/test.fifo",0664)<0) { if(errno==EEXIST) { //如果我們去創建我們的文件,返回的錯誤值是EEXIST代表這個文件已經存在了,這時候正常繼續就可以 } else { perror("mkfifo error
"); return -1; } } int fd=open("./test.fifo",O_WRONLY); if(fd<0) { perror("open error
"); return -1; } printf("success: write!
"); while(1) { char buff[1024]; scanf("%s",buff); write(fd,buff,strlen(buff)); } close(fd); return 0; } 這是我們的向fifo文件中寫數據的程序。 //這是實現管道寫的程序 #include #include #include #include #include #include int main() { umask(0); if(mkfifo("./test.fifo",0664)<0) { if(errno==EEXIST) { } else { perror("mkfifo error
"); return -1; } } int fd=open("./test.fifo",O_RDONLY); if(fd<0) { perror("open error
"); return -1; } printf("success read
"); while(1) { char buff[1024]={0}; int ret=read(fd,buff,1023); if(ret>0) { printf("client say:%s
",buff); } else { if(ret==0) { printf("all write port close
"); sleep(1); } } } close(fd); return 0; } 這是我們從fifo中讀數據的文件。 這裡我們要說幾個需要注意的點,因為我們可能會在程序里創建某一個許可權的文件,所以我們需要獲取管理員許可權才能去執行我們的程序。我們在打開文件的時候用的是open函數,open函數是會給我們提供選項,讓我們選擇是只讀只寫還是讀寫打開。如果是只讀打開,那open函數會阻塞, 只到有另一個進程以只寫的方式打開我們文件,同樣如果是只寫打開我們的文件也會阻塞,只到有一個進程以只讀的方式打開這個命名管道,如果我們open以讀寫的方式打開就不會阻塞,所以在運行程序的時候你會發現執行程序之後什麼反應都沒有,只到讀寫兩個程序都運行才會輸出success。還有最後一個特性,就是我們在讀端裡邊寫的,當然我們也可以設置把默認阻塞的變成非阻塞的O_RDONLY|O_NONBLOCK 這樣設置就好了。 int ret=read(fd,buff,1023); if(ret>0) { printf("client say:%s
",buff); } else { if(ret==0) { printf("all write port close
"); sleep(1); } } 如果讀取成功read函數會返回我們的實際上讀取到的值,這裡也是一樣,到那時如果說我們的管道裡邊所有的寫端全都關閉的時候,會返回ret0值,所以我們這裡寫了一個如果ret等於0我們就輸出所有寫埠已經關閉。 我們開兩個終端來分別運行我們的兩個讀寫程序 兩邊都啟動之後我們的會出現打開成功的字樣,並且我們在寫入端輸入一個程序之後,讀取端就會輸出對應的內容。 如果說我們把寫入端關閉之後,我們的讀取端會返回所有寫入端都已經關閉的字樣。 我們算是實現了通過命名管道文件實現服務端和客戶端的簡單通信 這麼簡單的也比我們寫的複雜....畢竟我的是只有一個讀一個寫,但是我們可以通過fifo實現複雜一些的程序 像這樣的

Linux講解 進程間通信 命名管道

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Jenkins+RobotFramework持續集成測試-jenkins環境搭建
Go image網站開發

TAG:程序員小新人學習 |