初識Linux/C語言編程,管道和重定向暨fork與execlp函數的理解

初識Linux/C語言編程,管道和重定向暨fork與execlp函數的理解

Linux中C語言的編程有兩個Windows環境下根本無須考慮的問題,關於管道和重定向的概念。

fork函數是讓程序創建一個跟自己一模一樣的副本,就跟當下流行的很多網絡遊戲中副本的概念差不多,昨晚在練習的時候忽然感到,這玩意兒又有點像WEB 編程中的表單自提交。在同一個程序裏面寫兩套方案,運行時讓其中的一套(安排在fork>=1的分支結構中)調用來自自身代碼文件中的另一套方案 (安排在fork==0分支結構)乍一看這跟管道根本就挨不着邊,我一開始也是覺得這樣,就像一個進程又去調用了一個進程一樣,不過另外調用的進程又是本 身,大腦裏一團漿糊一樣。那麼請看代碼吧:
  1. /**//*
  2. ============================================================================
  3. Name        : fork_example.c
  4. Author      : newflypig
  5. Version     :
  6. Copyright   : Your copyright notice
  7. Description : Hello World in C, Ansi-style
  8. ============================================================================
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <sys/types.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <sys/stat.h>
  16. int main(void) ...{
  17.     int i=1;
  18.     printf("in the begining,the value=%d ",i);
  19.     switch(fork())...{
  20.     case -1:
  21.         fprintf(stderr,"%s ","fork error");
  22.         break;
  23.     case 0:
  24.         printf("child process start,at this time value=%d ",i);
  25.         i++;
  26.         printf("child process end,at this time value=%d ",i);
  27.         break;
  28.     default:
  29.         printf("parent process: value=%d ",i);
  30.     }
  31.     return 0;
  32. }
複製代碼
運行結果是這樣的:

in the begining,the value=1
child process start,at this time value=1
child process end,at this time value=2
parent process: value=1

可 以看到父進程首先設置i=1然後調用子進程,子進程一開始就有了父進程的i值,然後子進程在自己的基礎上將i++了,子進程結束時輸出了i=2。當程序返 回父進程時,子進程的改變並沒有影響父進程中i的值,i依然爲1。這個fork()的功能僅僅如此,有誰會想到讓這個函數在Linux最具特色的管道機制 中大顯伸手呢。

花開兩朵,各表一枝。

下面看看重定向的概念:

先做一個演示程序:
  1. /**//*
  2. ============================================================================
  3. Name        : execlp_example.c
  4. Author      : newflypig
  5. Version     :
  6. Copyright   : Your copyright notice
  7. Description : Hello World in C, Ansi-style
  8. ============================================================================
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <sys/types.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <sys/stat.h>
  16. int main(void) ...{
  17.     int filedes;
  18.             if((filedes=open("dd.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0)
  19.         fprintf(stderr,"%s ","open file error");
  20.     close(1);
  21.     dup(filedes);
  22.     close(filedes);
  23.     execlp("ls","-l",(char * )0);
  24.     return 0;
  25. }
複製代碼
這是一段輸出重定向的程序,爲了解釋方便,首先了解一下Linux中標準輸入輸出文件,Linux中基本上所有的元素都可以理解爲文件,包括文件夾,設備等。程序中,首先使用close(1)關閉標準輸出端子,{/*當然如果你想輸入重定向的話可以關閉標準輸入端子,它的序列是0;序列爲3的端子是異常拋出端子,一般可以讓此端子與輸出設備保持一致。*/}, 然後使用dup函數將main函數的第一步所創建的名爲dd.txt的文件設置爲此程序的輸出設備。接着要關閉該文件的連接,釋放資源鎖以便讓程序來對此 文件進行讀寫。最後一步調用execlp函數進行命令的執行,這裏執行了一個ls的命令,讓當前目錄下的所有文件名輸出,execlp函數是可變參數函 數,第一個參數需要設置系統環境變量中所能獲取的命令文件,或者自己設置絕對路徑的命令文件,最後一個參數必須設置爲空,以便標記這個函數的參數已經設置 完成,中間的所有參數設置爲第一個命令的參數,如此段程序其實是執行ls -l這個命令。這樣就將輸出信息不直接打印到終端而輸出到dd.txt文本文件中,完成輸出重定向。

回到管道的問題上來。

如果將 剛剛講得重定向技術配合fork()進程產生函數,便可以實現管道的作用了。這裏說一下思路,就不給具體代碼了,也就是設置兩個全局的文件變量,將子進程 的輸出重定向到其中一個文件變量,因爲是全局變量,這個文件變量就被子進程徹底修改了,然後將父進程的輸入重定向到剛剛子進程的輸出,以此來完成 Linux中的管道機制。

不知各位看觀對本人關於Linux中的管道以及重定向問題的看法是否認同,昨晚就看這兩個函數的API和源代碼了。

綜上所述,一個毋庸置疑的結論:Linux編程比Windows編程艱鉅而有趣多了。以前從來不高興碰C語言,認爲C++和java此類OO語言纔是最人性化,最舒服的編程語言,這次初探C,感受到是另一種源於代碼和算法的舒服感。
發佈了15 篇原創文章 · 獲贊 14 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章