當程序間可以共享資料, 并且可以等待其他程序是否執行完畢時, 程式将變得更加強大.
顯然共享資料和等待都是内部程序通信的範疇, 這裡主要講一下 data stream.
每個程序都有一個descriptor table, 這個表包含了file descriptor(a number) 和 data stream的映射關系. 如圖 :
預設會有3條映射關系, 0, 1 , 2 分别代表stdin, stdout, stderr.
這裡的映射關系可以通過dup2 系統函數來修改, 例如要把database connection 這個data stream放到1對應的data stream上. 執行 dup2(3,1) .
當使用open打開一個檔案的時候, 會在descriptor table裡面尋找有沒有空的slot, 找到數值最小的空閑slot, 然後在這個file descriptor上建立一條映射. 這個descriptor table最大可以存儲255條映射.
在指令行中使用> <進行重定向時 , 例如 :
1>? 表示标準輸出重定向到?,
2>?表示标準錯誤重定向到?.
還可以使用&1,&2.
例如2>? 1>&2 表示标準錯誤重定向到?, 并且标準輸出重定向到标準錯誤.
接下來這個程式使用fopen建立一個檔案資料流, 并使用dup2将這個資料流放置到 file descriptor= 1 (也就是stdout) 的條目上. 然後往stdout和這個file data stream分别寫入一條消息. 看看是不是都會寫入同一個檔案.
編譯 :
執行 :
使用fprintf寫入 stdout和my_file 都寫到了/tmp/my_file.log
下面穿插一個 fork 和 waitpid 的使用場景.
為什麼主程序要等待子程序執行完畢呢?
來看個例子 :
沒有任何内容, 因為子程序還在執行, 并沒有往/tmp/my_file.log寫入任何資訊.
等待100秒後再次檢視這個檔案的内容就有了.
像這種場景, 如果主程序等待子程序執行結束則不會發生誤解.
修改代碼如下 :
如果waitpid等待的程序号不是子程序的程序号會怎麼樣呢?
【參考】
dup, dup2 :
wait, waitpid
fopen
fclose
fsync, fdatasync
exit
fileno