進程間通信——重定向、描述符表

      網友投稿 810 2022-05-28

      在命令行運行程序時,可以用“>"運算符把標準輸出重定向到文件:

      ~/Desktop/Mc$ echo "hello world" > log.txt ~/Desktop/Mc$ tail -f log.txt hello world

      1

      2

      3

      標準輸入、標準輸出、標準錯誤是三大默認數據流,除此之外還有其他形式的數據流,如文件連接和網絡連接也屬于數據流。數據流就是流動的數據,數據從一個進程流出,然后流入另一個進程。

      重定向進程的輸出,相當于改變進程發送數據的方向。如上面的例子,原本標準輸出會把數據發送到屏幕,現在讓它把數據發送到文件。

      進程含有它正在運行的程序,還有棧和堆空間。除此之外,進程還需要記錄數據流的連向,比如標準輸出連到了哪里。這些記錄記在哪里呢?答案就是描述符表。進程用文件描述符表示數據流,所謂的描述符其實就是一個數字。進程會把文件描述符和對應的數據流保存在描述符表中。

      描述符表

      描述符表的一列是文件描述符號,另一列是它們對應的數據流。雖然名字叫文件描述符,但它們不一定連接硬盤上的某個文件,也可能連接鍵盤、屏幕、文件指針、網絡。

      描述符表的前三項是不會變的:0號標準輸入、1號標準輸出、2號標準錯誤。其他項要么為空,要么連接進程打開的數據流。比如程序在打開文件進行讀寫時,就會占用其中一項。描述符表的大小是從0到255號。

      創建進程以后,標準輸入連接到鍵盤,標準輸出和標準錯誤連接到屏幕。它會保持這樣的連接,直到有人把它們重定向到了其他地方。

      重定向就是替換數據流

      標準輸入/輸出/錯誤在描述符表中的位置是固定的,但它們指向的數據流是可以改變的。例如想重定向標準輸出,只需要修改表中1號描述符對應的數據流就OK了。

      所有向標準輸出發送數據的函數會先查看描述符表,看1號描述符指向哪條數據流,然后再把數據寫到這條數據流中,printf()函數就是這樣。

      進程可以重定向自己

      在命令行中可以用“>“和”<"運算符重定向程序。進程也能重定向它們自己,只需修改描述符表。只需要兩步就可以實現:

      1.fileno()返回文件描述符號

      每打開一個文件,操作系統都會在描述符表中新注冊一項。假設我們打開了log.txt文件:

      FILE *my_file = fopen("log.txt","w");

      1

      操作系統會打開log.txt文件,然后返回一個指向它的指針,操作系統還會遍歷描述符表找空項,把新文件注冊在其中。

      int descriptor = fileno(my_file);

      1

      在失敗時不返回-1的函數很少,fileno()就是其中之一。只要你把打開文件的文件指針傳給fileno(),它就一定會返回描述符編號。

      2.dup2()復制數據流

      每次打開文件都會使用描述符表中新的一項。但如果你想修改某個已經注冊過的數據流,比如讓1號文件描述符重新指向其他數據流,就可以用dup2()函數來實現,dup2()可以復制數據流,假設我們在3號文件描述符中注冊了log.txt文件指針,下面代碼就可以同時把文件指針連接到1號描述符:

      dup2(3,1);

      1

      雖然log.txt文件只有一個,與它相連的數據流也只有一個,但是數據流(FILE *)同時注冊在文件描述符1和3中。所以標準輸出都會被重定向到文件log.txt中。

      我們看一個完整的實例:

      #include #include #include #include int main(){ FILE *my_file = fopen("log.txt","w"); int descriptor = fileno(my_file); dup2(descriptor,1); printf("Hello world,I love you!\n"); return 0; }

      1

      2

      3

      4

      5

      6

      進程間通信——重定向、描述符表

      7

      8

      9

      10

      11

      12

      13

      14

      編譯運行:

      ~/Desktop/MyC$ gcc test4.c -o test4 ~/Desktop/MyC$ ./test4 ~/Desktop/MyC$ tail -f log.txt Hello world,I love you!

      1

      2

      3

      4

      用管道連接輸入與輸出,符號“|”表示管道(pipe),它能連接一個進程的標準輸出與另一個進程的標準輸入。

      如:

      ~/Desktop/MyC$ ls /usr/include | grep stdio stdio_ext.h stdio.h

      1

      2

      3

      ls程序的標準輸出會連接到grep程序的標準輸入。

      謝謝閱讀!

      任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:(更新時間)2021年06月22日 網絡安全 NTFS安全權限
      下一篇:日交易額百億級交易系統的超輕量日志實現
      相關文章
      久久久久无码精品亚洲日韩| 亚洲成在人线av| 亚洲福利视频一区二区三区| 久久青青草原亚洲AV无码麻豆| 国产精品亚洲美女久久久| 亚洲精品高清在线| 亚洲AV中文无码乱人伦| 国产亚洲情侣久久精品| 亚洲国产成人久久综合野外| 日韩精品亚洲专区在线观看| 最新亚洲人成网站在线观看| 国产成人亚洲精品91专区高清 | 337P日本欧洲亚洲大胆精品| 亚洲日产乱码一二三区别| 亚洲日韩精品国产一区二区三区| 午夜在线a亚洲v天堂网2019| 亚洲熟妇丰满xxxxx| 久久精品亚洲日本波多野结衣| 国产成人亚洲精品无码AV大片| 亚洲国产中文v高清在线观看| 亚洲男人的天堂在线va拉文| 亚洲综合另类小说色区| 亚洲成色在线综合网站| 亚洲人成影院在线| 亚洲欧洲综合在线| 亚洲人成网国产最新在线| 亚洲色大成网站www永久男同| 婷婷亚洲综合一区二区| 亚洲精品国精品久久99热| 国产亚洲av人片在线观看| 亚洲国产精品VA在线看黑人| 亚洲av日韩av无码| 亚洲成人福利在线观看| 国产精品亚洲自在线播放页码| 亚洲免费网站观看视频| 亚洲国产精品激情在线观看| 亚洲日韩欧洲乱码AV夜夜摸| 亚洲视频免费在线观看| 亚洲乱码一二三四五六区| 亚洲国产精品嫩草影院| 亚洲精品无码av天堂|