首頁 運維 linux運維 伺服器程式設計中對於檔案的操作詳解

伺服器程式設計中對於檔案的操作詳解

Jun 20, 2017 am 11:57 AM
文件 伺服器 程式設計

  linux系統下一切皆文件,透過虛擬檔案系統(VFS)的機制將所有底層屏蔽掉,使用者可以透過統一的介面來實現對不同驅動程式的操作,對於每一個檔案需要一個引用來指示,此時檔案描述子應用程式而生,檔案描述子類似於widows下的handle,對於檔案的大部分操作都是透過這個描述符來操作的,例如read,write。對於每一個檔案描述符,核心使用三種資料結構來管理。

(1)  每個行程在行程表中都有一個記錄項,每個記錄項中都有一個開啟檔案描述符表,可將其視為一個向量,每個描述符佔用一項。與每個檔案描述子相關聯的是:

  (a)  檔案描述符標誌。 (目前只定義了一個檔案描述符標誌FD_CLOEXEC)

  (b)  指向一個檔案表項的指標。

(2)  核心為所有開啟檔案維持一張檔案表。每個文件表項包含:

  (a)  檔案狀態標誌(讀取、寫入、增寫、同步、非阻塞等 )。

  (b)  目前檔案位移量。 (即為lseek函數所操作的值)

  (c)  指向該檔案v節點表項的指標。

(3)  每個開啟檔案(或裝置)都有一個 v 節點結構。 v節點包含了檔案類型和對此檔案進#行各種操作的函數的指標資訊。對於大多數文件, v 節點也包含了該文件的 i 節點(索引節點)。這些資訊是在開啟檔案時從碟上讀入記憶體的,所以所有關於檔案的資訊都是快速可供使用的。例如, i 節點包含了檔案的擁有者、檔案長度、檔案所在的裝置、指向檔案在磁碟上所使用的實際資料區塊的指標等等點。

 

  經過上述檔案系統的三層封裝,每層負責不同的職責,從上到下第一層用於識別文件,第二層用於管理進程獨立數據,第三層管理文件系統元數據,直接關聯一個文件。這種分層思想的一個優點就是上層可以重複使用下層的結構。可能有多個檔案描述符項指向同一個檔案表項,也可以有多個檔案表項指向同一個V節點。

  如果兩個獨立的進程打開了同一個文件,打開此文件的每個進程都得到一個文件表項,但是兩個文件表項的V節點指針指向相同的V節點,這樣的安排使得每個進程都有他自己的對該檔案的當前位移量,並且支援不同的開啟方式(O_RDONLY, O_WRONLY, ORDWR)。

  當一個進程透過fork建立出子進程後,此時父,子進程內的檔案描述符共享同一個檔案表項,也就是說父子進程的檔案描述符的指向相同。一般我們會在fork後關閉掉各自不需要的fd,例如父子進程透過pipe或socketpair進行通信,往往會close掉自己不需要讀(或寫)的一端。只有在沒有檔案描述子引用目前文件表項的時候,close操作才真正銷毀目前文件表項資料結構,有點類似引用計數的想法。這也是網路程式設計中close和shutdown函數的區別,前者只有在最後一個使用該socket的句柄的進程關閉的時候才真正斷開連接,而後者毫不商量直接斷開一側連接。但在多執行緒的環境中,由於父子執行緒共享位址空間,此時檔案描述子共同擁有,只有一份,所以也就不能在執行緒內close掉自己不需要的fd,否則會導致其它需要該fd的線程也受影響。因為父,子進程內打開的檔案描述符共享同一個檔案表項,所以在某些系統的伺服器程式設計中,如果採用preforking模型(伺服器預先派生多個子進程,在每個子進程監聽listenfd來accept連接)就會導致驚群現象的發生,伺服器派生的多個子進程各自調用accept並因而均被投入睡眠,當第一個客戶連接到達時,儘管只有一個進程獲得連接,但是所有進程都被喚醒,這樣導致性能受損。參見UNP P657。

  同時如果fork之後呼叫exec,所有的檔案描述子繼續保持開啟狀態。這可以用來給exec後的程式傳遞某些檔案描述符。同時檔案描述符標誌FD_CLOEXEC 就是用來關閉exec時繼續保持開放的檔案描述符的選項。

  也可以透過dup或fcntl明確複製一個檔案描述符,他們指向相同的檔案表項。透過dup2將檔案描述符複製到製定數值。

  每個進程都有一個檔案描述子表,進程間獨立,兩個進程之間的檔案描述子並無直接關係,所以在進程內可以直接傳遞檔案描述符,但是如果跨越進程傳遞就失去了意義,unix可以透過sendmsg/recvmsg進行專門的檔案描述符的傳遞(參見書UNP 15.7節)。每個行程的前三個檔案描述子分別對應標準輸入,標準輸出,標準錯誤。但是一個進程可開啟的檔案描述符數量是有限制的,如果開啟的檔案描述符太多會出現」Too many open files」的問題。在網頁伺服器中,透過listenfd呼叫呼叫accept時,體現為產生EMFILE錯誤,這主要是因為檔案描述子是系統的重要資源,系統資源是有盡的,系統對單一進程檔案描述子限制預設值一般是1024,使用ulimit -n指令可以查看。當然也可以調高進程檔案描述符數目,但這是治標不治本的方法,因為處理高並發服務時,伺服器資源有限,難免資源枯竭。

  當結合epoll的水平觸發方式來監聽lisenfd的連接時,大量socket連接湧來如果不處理會塞滿TCP的連接隊列,listenfd會一直產生可讀事件,將伺服器陷入忙碌等待,用C++開源網路庫muduo作者陳碩的做法是事先準備一個空閒的文件描述符,當產生EMFILE錯誤時就先關閉這個空閒文件,獲得一個文件描述符名額,再accept拿到一個socket連接的文件描述符,隨後立刻close,這樣就優雅的斷開了與客戶端的連接,最後重新打開空閒文件,把”坑”填上,以備再次出現這種情況時使用。

 1 //在程序开头先”占用”一个文件描述符 2  3 int idlefd = open("/dev/null", O_RDONLY | O_CLOEXEC); 4 ………… 5  6 //然后当出现EMFILE错误的时候处理这个错误 7  8 peerlen = sizeof(peeraddr); 9 connfd = accept4(listenfd,  (struct sockaddr*)&peeraddr, &peerlen, SOCK_NONBLOCK | SOCK_CLOEXEC);10 11 if (connfd == -1)12 {13     if (errno == EMFILE)14     {15         close(idlefd);16         idlefd = accept(listenfd, NULL, NULL);17         close(idlefd);18         idlefd = open("/dev/null", O_RDONLY | O_CLOEXEC);19         continue;20     }21     else22         ERR_EXIT("accept4");23 }
登入後複製
#

以上是伺服器程式設計中對於檔案的操作詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1274
29
C# 教程
1256
24
使用正規表示式去除 PHP 數組中的重複值 使用正規表示式去除 PHP 數組中的重複值 Apr 26, 2024 pm 04:33 PM

使用正規表示式從PHP數組中移除重複值的方法:使用正規表示式/(.*)(.+)/i匹配並取代重複項。遍歷數組元素,使用preg_match檢查匹配情況。如果匹配,請跳過值;否則,將其添加到無重複值的新數組中。

搭載 AMD EPYC 霄龍 4004 系列處理器,華碩推出多款伺服器與工作站產品 搭載 AMD EPYC 霄龍 4004 系列處理器,華碩推出多款伺服器與工作站產品 Jul 23, 2024 pm 09:34 PM

本站7月23日消息,華碩推出多款由AMDEPYC霄龍4004系列處理器驅動的伺服器與工作站級產品。本站註:AMD於5月推出AM5平台、Zen4架構的EPYC霄龍4004系列處理器,最高提供16核心3DV-Cache規格。 ASUSProER100AB6伺服器ASUSProER100AB6是一款搭載EPYC霄龍4004系列處理器的1U機架式伺服器產品,適用於IDC及中小型企業需求。 ASUSExpertCenterProET500AB6工作站ASUSExpertCenterProET500AB6是一款A

釋放你內心的程式設計師:C 絕對初學者 釋放你內心的程式設計師:C 絕對初學者 Oct 11, 2024 pm 03:50 PM

C語言是初學者學習程式設計的理想選擇,其優點包括效率、多功能性和可移植性。學習C語言需要:安裝C編譯器(如MinGW或Cygwin)了解變數、資料型別、條件語句和迴圈語句編寫包含主函數和printf()函數的第一個程式透過實戰案例(如計算平均數)練習C語言知識

程式設計是乾啥的,學了有什麼用 程式設計是乾啥的,學了有什麼用 Apr 28, 2024 pm 01:34 PM

1、程式設計可用於開發各種軟體和應用程序,包括網站、手機應用程式、遊戲和數據分析工具等。它的應用領域非常廣泛,幾乎涵蓋了所有行業,包括科學研究、醫療保健、金融、教育、娛樂等。 2.學習程式設計可以幫助我們提升問題解決能力和邏輯思考能力。在程式設計過程中,我們需要分析和理解問題,找出解決方案,並將其轉換為程式碼。這種思維方式能夠培養我們的分析和抽象能力,提升我們解決實際問題的能力。

使用 Python 解決問題:作為初學者,解鎖強大的解決方案 使用 Python 解決問題:作為初學者,解鎖強大的解決方案 Oct 11, 2024 pm 08:58 PM

Python 讓初學者能夠解決問題。

Python 的力量,簡單:一種適合初學者的程式設計方法 Python 的力量,簡單:一種適合初學者的程式設計方法 Oct 11, 2024 pm 04:53 PM

Python程式設計入門安裝Python:從官方網站下載並安裝。 HelloWorld!:使用print("HelloWorld!")列印第一行程式碼。實戰案例:計算圓面積:使用π(3.14159)和半徑計算圓面積。變數和資料類型:使用變數儲存數據,Python中的資料類型包括整數、浮點數、字串和布林值。表達式與賦值:使用運算子將變數、常數和函數連接起來,並使用賦值運算子(=)將值賦給變數。控制流程:if-else語句:根據條件執行不同的程式碼區塊,確定奇

C++ 程式設計謎題片段:激發思維,提升程式設計水平 C++ 程式設計謎題片段:激發思維,提升程式設計水平 Jun 01, 2024 pm 10:26 PM

C++程式設計謎題涵蓋斐波那契數列、階乘、漢明距離、陣列最大值和最小值等演算法和資料結構概念,透過解決這些謎題,可以鞏固C++知識,提升演算法理解和程式設計技巧。

編碼的關鍵:為初學者釋放 Python 的力量 編碼的關鍵:為初學者釋放 Python 的力量 Oct 11, 2024 pm 12:17 PM

Python透過其易學性和​​強大功能,是初學者的理想程式設計入門語言。其基礎包括:變數:用於儲存資料(數字、字串、列表等)。資料型態:定義變數中資料的型態(整數、浮點數等)。運算符:用於數學運算和比較。控制流程:控製程式碼執行流程(條件語句、迴圈)。

See all articles