UNIX高級環境編程(14)文件IO - O_DIRECT和O_SYNC詳解 < 海棠花溪 >

来源:http://www.cnblogs.com/suzhou/archive/2016/04/12/5381738.html
-Advertisement-
Play Games

春天來了,除了工作學習,大家也要註意鍛煉身體,多出去運動運動。上周末在元大都遺址公園海棠花溪拍的海棠花。進入正題。O_DIRECT和O_SYNC是系統調用open的flag參數。通過指定open的flag參數,以特定的文件描述符打開某一文件。這兩個flag會對寫盤的性能有很大的影響,因此對這兩個fl... ...


春天來了,除了工作學習,大家也要註意鍛煉身體,多出去運動運動。 

上周末在元大都遺址公園海棠花溪拍的海棠花。

DSC 2639 01

 

進入正題。

O_DIRECT和O_SYNC是系統調用open的flag參數。通過指定open的flag參數,以特定的文件描述符打開某一文件。

這兩個flag會對寫盤的性能有很大的影響,因此對這兩個flag做一些詳細的瞭解。

先看一個open函數的使用例子.

/* Open new or existing file for reading and wrting,
    sync io and no buffer io; file permissions read+
    write for owner, nothing for all others */
fd = open("myfile", O_RDWR | O_CREAT | O_SYNC | O_DIRECT, S_IRUSR | S_IWUSR);
if (fd == -1)
    errExit("open");

 O_DIRECT: 無緩衝的輸入、輸出。 O_SYNC:以同步IO方式打開文件。 下麵對這兩個flag做一些詳細的說明。  

一,O_DIRECT,繞過緩衝區高速緩存,直接IO

直接IO:Linux允許應用程式在執行磁碟IO時繞過緩衝區高速緩存,從用戶空間直接將數據傳遞到文件或磁碟設備,稱為直接IO(direct IO)或者裸IO(raw IO)。 應用場景:資料庫系統,其高速緩存和IO優化機制均自成一體,無需內核消耗CPU時間和記憶體去完成相同的任務。 使用直接IO的弊端:可能會大大降低性能,內核對緩衝區告訴緩存做了不少優化,包括:按順序預讀取,在成簇磁碟塊上執行IO,允許訪問同一文件的多個進程共用高速緩存的緩衝區。 使用方法:在調用open函數打開文件或設備時指定O_DIRECT標誌。 註意可能發生的不一致性:若一進程以O_DIRECT標誌打開某文件,而另一進程以普通(即使用了高速緩存緩衝區)打開同一文件,則由直接IO所讀寫的數據與緩衝區高速緩存中內容之間不存在一致性,應儘量避免這一場景。   使用直接IO需要遵守的一些限制:
  • 用於傳遞數據的緩衝區,其記憶體邊界必須對齊為塊大小的整數倍
  • 數據傳輸的開始點,即文件和設備的偏移量,必須是塊大小的整數倍
  • 待傳遞數據的長度必須是塊大小的整數倍。

不遵守上述任一限制均將導致EINVAL錯誤。

 

二,O_SYNC,以同步方式寫入文件

功能:強制刷新內核緩衝區到輸出文件。這是有必要的,因為為了數據安全,需要確保將數據真正寫入磁碟或者磁碟的硬體告訴緩存中。

我們先熟悉一下同步IO相關定義和系統調用。

同步IO數據完整性和同步IO文件完整性

同步IO的定義:某一IO操作,要麼已成功完成到磁碟的數據傳遞,要麼被診斷為不成功。 SUSv3定義的兩種同步IO完成類型(此處用英文,因為譯者也忍無可忍用了原文…)
  • synchronized IO data integrity completion:確保針對文件的一次更新傳遞了足夠的信息(部分文件元數據)到磁碟,以便於之後對數據的獲取。
  • synchronized IO file integrity completion:確保針對文件的一次更新傳遞了所有的信息(所有文件元數據)到磁碟,即使有些在後續對文件數據的操作並不需要。

用於控制文件IO內核緩衝的系統調用

1 fsync

作用:fsync()系統調用將使緩衝數據和fd相關的所有元數據都刷新到磁碟上。調用fsync會強制使文件處於Synchronized IO file integrity completion狀態。 函數聲明:
#include
int fsync(int fd);

函數返回值:
  • 0: success
  • -1: error
返回時間:僅在對磁碟設備(或者至少是其高速緩存)的傳遞完成後,fsync()調用才會返回。   2 fdatasync 作用:fdatasync()系統調用的作用類似fsync(),只是強制文件處於synchronized IO data integrity compeletion狀態。 函數聲明:
#include
int fdatasync(int fd);

函數返回值:
  • 0: success
  • -1: error
與fsync的區別:fdatasync()可能會減少磁碟操作的次數,由fsync()調用請求的兩次變成一次。例如,修改了文件的數據,而文件大小不變,那麼調用fdatasync調用請求只強制進行了數據更新,相比之下,fsync()調用會強制將元數據傳遞到磁碟上,而元數據和文件數據通常駐留在磁碟的不同區域,更新這些數據需要反覆在整個磁碟上執行尋道操作。   3 sync系統調用 作用:sync()系統調用會使包含更新文件信息的所有內核緩衝區(即數據塊、指針塊、元數據等)刷新到磁碟上。 函數聲明:
#include
void sync(void);

細節:若內容發生變化的內核緩衝區在30s內未經顯式方式同步到磁碟上,則一條長期運行的內核線程會確保將其刷新到磁碟上。這一做法是為了規避緩衝區與相關磁碟文件內容長期處於不一致狀態。   4 使所有寫入同步:O_SYNC 調用open()函數時,如制定O_SYNC標誌,則會使所有後續輸出同步。
fd = open(pathname, O_WRONLY | O_SYNC);

作用:調用open後,每個write調用會自動將文件數據和元數據刷新到磁碟上,即按照Synchronized IO file integrity completion的要求執行寫操作。   5 有無O_SYNC性能對比 場景:將一百萬位元組寫入一個ext2文件系統上的新創建文件,比較寫入時間。 對比結果: NewImage 從結果中可以得到的結論:
  • 採用O_SYNC標誌(或者頻繁調用fsync(), fdatasync()或sync())對性能影響極大。
  • 性能下降的直接表現為運行總用時大為增加:在緩衝區為1位元組的情況下,運行時間相差1000多倍。
  • 以O_SYNC標誌執行寫操作時運行總用時和CPU時間之間的巨大差異(1030 - 98.8),原因是系統在每個緩衝區中將數據向磁碟傳遞時會把程式阻塞起來。
 

 三,IO緩衝層次關係

先總結一下stdio函數庫和內核採用的緩衝這兩級緩衝,然後用圖說明兩層緩衝機制和各種緩衝類型的控制機制。
  • 首先,通過stdio庫將用戶數據傳遞到stdio緩衝區,該緩衝區位於用戶態記憶體區。
  • 當緩衝區填滿,stdio庫會調用write()系統調用,將數據傳遞到內核高速緩衝區,該緩衝區位於內核態記憶體區。
  • 最終,內核發起磁碟操作。
該層次結構如下圖所示   NewImage

 

上圖中,左側虛線方框中為可於任何時刻顯式強制刷新各類緩衝區的調用。 右側所示為促使刷新自動化的調用:通過禁用stdio的緩衝,和在文件輸出類的系統調用中啟用同步,從而使每個write()調用立刻刷新到磁碟。  

四,小結

輸入輸出數據的緩衝由內核和stdio庫完成。有時可能希望阻止緩衝,但這需要瞭解其對應用程式性能的影響。 可以使用各種系統調用和庫函數來控制內核和stdio緩衝,並執行一次性的緩衝區刷新。 在Linux環境下,open()所特有的O_DIRECT標識允許特定應用跳過緩衝區高速緩存。    

雖然題目還是UNIX高級環境變成(xx),但是打算把所閱讀和參考的書換成《Linux/UNIX系統編程手冊》。感覺這本書內容更新一點。

工作很忙,周末大部分時間都在外面活動,跑步拍照,雖然只是簡單的讀書這一篇也是拖了又拖才敲完。

 

參考:

《Linux/UNIX系統編程手冊(上冊)》  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 操作步驟: 1.sudo apt-get autoremove(卸載系統中所有未被使用的依賴關係) 2.sudo apt-get clean(清除所有緩存的包文件) 以上操作綠色無害,對系統無影響。 ...
  • 方法一: 操作步驟:進入cmd命令界面-->輸入:net use(查看列表)-->輸入:net use * /delete(清空列表)-->輸入:y 回車確認即可。 註意:操作後仍然無法解決,可嘗試註銷系統。若註銷後仍是不行,請嘗試第二種方法。 方法二: 操作步驟:控制面板-->用戶賬戶-->選擇:... ...
  • 一、交叉編譯libjepg編譯 tar xzf libjpeg-turbo-1.2.1.tar.gz ./configure –help ./configure --prefix=/work/project/first_project/13libjepg/libjpeg-turbo-1.2.1/tm... ...
  • 大叔學Linux就一個目的,部署在它上面的服務,如redis,mongodb,fastDFS,cat,docker,mysql,nginx等 下麵找一下的命令,來學學這個神秘的操作系統 常用指令 ls 顯示文件或目錄 -l 列出文件詳細信息l(list) -a 列出當前目錄下所有文件及目錄,包括隱藏 ...
  • 介紹 文件描述符是與文件輸入、輸出相關聯的整數,在編寫腳本時會經常使用標準的文件描述符來將內容重定向輸出,0、1、2是文件描述符(分別對應stdin、stdout、stderr),< 、>, >>叫做操作符。 概念 stdin(0):標準輸入,這個概念有點不太容易理解比如:1.使用<從文件中讀取內容 ...
  • windows2003下禁止用戶遠程登錄的方法如下: 1、打開控制面板 > 管理工具 > 本地安全策略 2、安全策略-->本地策略-->用戶許可權分配-->通過終端服務拒絕登錄,在裡面添加想要禁止遠程的用戶可以達到讓這個賬戶無法遠程 windows2008下禁止用戶遠程登錄的方法如下: 1、打開控制面... ...
  • ls:列出目錄內容 1、常用參數: -a, –all 列出目錄下的所有文件,包括以 . 開頭的隱含文件(常用) -A 同-a,但不列出“.”(表示當前目錄)和“..”(表示當前目錄的父目錄)。 -c 配合 -lt使用,例如使用ls -ltc則根據文件的change time排序,越靠近現在時間則優先 ...
  • mkdir:make directories(創建目錄) 創建目錄的首要條件:在當前目錄或者欲創建目錄下,該用戶具有寫入許可權,mkdir詳細功能如下: 1、mkdir不接任何參數時,即mkdir directorys表示在當前目錄下創建一個目錄 2、mkdir可以接絕對路徑或者相對路徑來創建目錄: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...