Linux系統編程15 系統調用IO - 系統IO和標準IO比較實例

文件IO 與 標準IO 的區別:

舉例:傳達室老大爺跑郵局
方法一:來一份郵件 跑一次郵局
方法二:積攢到自己能夠運載的郵件數量後,假設爲100封信。跑一次郵局
方法三:在接收郵件過程中,還沒有達到自己能夠運載的郵件數量100,忽然有一封加急郵件,則帶着加急郵件以及前面接收到的郵件,跑一次郵局。

老大爺送信任務相當於緩衝區操作,而加急動作相當於 fflush()刷新緩衝區。

標準IO 具有緩衝機制,也就是 標準IO 的操作,並不是操作完後就馬上執行,而是放到的當前文件的緩衝區中,等到 緩衝區 滿了 或者 換行 或者 強制刷新的時候,即適配 行緩衝,全緩衝,無緩衝等情況。 纔會一起執行動作。

系統調用IO 是 每調用一次就 實實在在的 從user態 切換到 kernel 態 去執行一次,也就是說 系統調用IO 的實時性非常高

所以說 系統調用IO的效應速度快。標準IO的吞吐量大,即可以合併系統調用IO

文件IO 轉換 標準IO :fileno(), fdopen()

標準IO 與 文件IO 不可以混用。
標準IO 與 文件IO 不可以混用,因爲 標準IO 操作後 如果沒有刷新,文件的改動並沒有寫道磁盤,也就說 與之對應的 文件IO 並沒有被執行,即 文件屬性結構體空間 中的信息並沒有與 FILE * 中的信息同步。按照下圖說明的話,就是 假如標準IO 執行兩次 fputc(fd)操作, 但是沒有刷新,那麼 FILE 中的 pos 有隨之 pos++, 但是由於可能沒有刷新緩衝區,則對應的文件並可能沒有改動,即對應的文件IO 中文件屬性結構體並沒有更新,此時文件屬性結構體中的pos 與 FILE中的pos ,j即文件當前位置指針是不一樣的,那麼什麼時候刷新緩衝區呢,即行緩衝,全緩衝,無緩衝等情況,緩衝後,文件屬性結構體中的pos一次性加到 FILE中的pos值。

類似於 我們再寫 world 的時候,寫到一半,關閉文檔,這時候會提示 是否保存已寫內容,這個提示就是 是否刷新緩衝區,此時的FILE 中信息 與 文件屬性結構體中信息並不同步,點擊“是”之後,表示刷新緩衝區,這時候纔會同步信息,即將改動的內容寫到磁盤。
在這裏插入圖片描述

實驗1: 標準IO 與 文件IO 混用

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
	putchar('a');
	write(1,"b",1);

	putchar('a');
	write(1,"b",1);

	putchar('a');
	write(1,"b",1);

	exit(0);
}
mhr@ubuntu:~/work/linux/sysio/15$ gcc ab.c 
mhr@ubuntu:~/work/linux/sysio/15$ ./a.out 
bbbaaamhr@ubuntu:~/work/linux/sysio/15$ 

輸出 bbbaaa

用 strace 命令查看 可執行程序的系統調用是如何發生的

mhr@ubuntu:~/work/linux/sysio/15$ 
mhr@ubuntu:~/work/linux/sysio/15$ strace ./a.out 
....
.....
.... 
write(1, "b", 1b)                        = 1
write(1, "b", 1b)                        = 1
write(1, "b", 1b)                        = 1
write(1, "aaa", 3aaa)                      = 3
exit_group(0)                           = ?
+++ exited with 0 +++
mhr@ubuntu:~/work/linux/sysio/15$ 

首先輸出三個 文件IO 的 b
write(1,“b”,1);
write(1,“b”,1);
write(1,“b”,1);

另外三個 標準IO 的
putchar(‘a’);
putchar(‘a’);
putchar(‘a’);
則是將 a 放在了輸出的緩衝區中,最後刷新緩衝區,即調用文件IO write(),用一次 write ,即 write(緩衝區中的所有a),注意並不是調用了多次 write, 而是隻調用一次write ,一次性把緩衝區中的內容全部寫進。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章