91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux I/O 接口的類(lèi)型及處理流程

科技綠洲 ? 來(lái)源:Linux開(kāi)發(fā)架構(gòu)之路 ? 作者:Linux開(kāi)發(fā)架構(gòu)之路 ? 2023-11-08 16:43 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux I/O 接口

Linux I/O 接口可以分為以下幾種類(lèi)型:

文件 I/O 接口:用于對(duì)文件進(jìn)行讀寫(xiě)操作的接口,包括 open()、read()、write()、close()、lseek() 等。

圖片

網(wǎng)絡(luò) I/O 接口:用于網(wǎng)絡(luò)通信的接口,包括 socket()、connect()、bind()、listen()、accept() 等。

圖片

設(shè)備 I/O 接口:用于對(duì)設(shè)備(e.g. 字符設(shè)備、塊設(shè)備)進(jìn)行讀寫(xiě)操作的接口,包括 ioctl()、mmap()、select()、poll()、epoll() 等。

其他 I/O 接口:如管道接口、共享內(nèi)存接口、信號(hào)量接口等。

Linux I/O 處理流程

下面以最常用的 read() 和 write() 函數(shù)來(lái)介紹 Linux 的 I/O 處理流程。

read() 和 write()

read() 和 write() 函數(shù),是最基本的文件 I/O 接口,也可用于在 TCP Socket 中進(jìn)行數(shù)據(jù)讀寫(xiě),屬于阻塞式 I/O(Blocking I/O),即:如果沒(méi)有可讀數(shù)據(jù)或者對(duì)端的接收緩沖區(qū)已滿(mǎn),則函數(shù)將一直等待直到有數(shù)據(jù)可讀或者對(duì)端緩沖區(qū)可寫(xiě)。

函數(shù)原型:

fd 參數(shù):指示 fd 文件描述符。

buf 參數(shù):指示 read/write 緩沖區(qū)的入口地址。

count 參數(shù):指示 read/write 數(shù)據(jù)的大小,單位為 Byte。

函數(shù)返回值:

  • 返回實(shí)際 read/write 的字節(jié)數(shù)。
  • 返回 0,表示已到達(dá)文件末尾。
  • 返回 -1,表示操作失敗,可以通過(guò) errno 全局變量來(lái)獲取具體的錯(cuò)誤碼。
#include

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

處理流程

下面以同時(shí)涉及了 Storage I/O 和 Network I/O 的一次網(wǎng)絡(luò)文件下載操作來(lái)展開(kāi) read() 和 write() 的處理流程。

read() 的處理流程:

  1. Application 調(diào)用 read(),CPU 模式從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. Kernel 根據(jù) file fd 查表(進(jìn)程文件符表),找到對(duì)應(yīng)的 file 結(jié)構(gòu)體(普通文件),從而找到此文件的 inode 編號(hào)。
  3. Kernel 將 buf 和 count 參數(shù)、以及文件指針位置等信息傳遞給 Device Driver(磁盤(pán)驅(qū)動(dòng)程序)。
  4. Driver 將請(qǐng)求的數(shù)據(jù)從 Disk Device 中 DMA Copy 到 Kernel PageCache Buffer 中。
  5. Kernel 將數(shù)據(jù)從 Kernel PageCache Buffer 中 CPU Copy 到 Userspace Buffer 中(Application 不能直接訪問(wèn) Kernel space)。
  6. read() 最終返回讀取的字節(jié)數(shù)或錯(cuò)誤代碼給 Application,CPU 模式從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

write() 的處理流程:

  1. Application 調(diào)用 write(),CPU 模式從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. Kernel 根據(jù) socket fd 查表,找到對(duì)應(yīng)的 file 結(jié)構(gòu)體(套接字文件),從而找到該 Socket 的 sock 結(jié)構(gòu)體。
  3. Kernel 將 buf 和 count 參數(shù)、以及文件指針位置等信息傳遞給 Device Driver(網(wǎng)卡驅(qū)動(dòng)程序)。
  4. Driver 將請(qǐng)求的數(shù)據(jù)從 Userspace Buffer 中 CPU Copy 到 Kernel Socket Buffer 中。
  5. Kernel 將數(shù)據(jù)從 Kernel Socket Buffer 中 DMA Copy 到 NIC Device。
  6. write() 最終返回寫(xiě)入的字節(jié)數(shù)或錯(cuò)誤代碼給 Application,CPU 模式從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

可見(jiàn),在一次常規(guī)的 I/O(read/write)操作流程中 處理流程中,總共需要涉及到:

  • 4 次 CPU 模式切換:當(dāng) Application 調(diào)用 SCI 時(shí),CPU 從用戶(hù)態(tài)切換到內(nèi)核態(tài);當(dāng) SCI 返回時(shí),CPU 從內(nèi)核態(tài)切換回用戶(hù)態(tài)。
  • 2 次 CPU Copy:CPU 執(zhí)行進(jìn)程數(shù)據(jù)拷貝指令,將數(shù)據(jù)從 User Process 虛擬地址空間 Copy 到 Kernel 虛擬地址空間。
  • 2 次 DMA Copy:CPU 向 DMA 控制器下達(dá)設(shè)備數(shù)據(jù)拷貝指令,將數(shù)據(jù)從 DMA 物理內(nèi)存空間 Copy 到 Kernel 虛擬地址空間。

圖片

I/O 性能優(yōu)化機(jī)制

I/O buff/cache

Linux Kernel 為了提高 I/O 性能,劃分了一部分物理內(nèi)存空間作為 I/O buff/cache,也就是內(nèi)核緩沖區(qū)。當(dāng) Kernel 接收到 read() / write() 等讀寫(xiě)請(qǐng)求時(shí),首先會(huì)到 buff/cache 查找,如果找到,則立即返回。如果沒(méi)有則通過(guò)驅(qū)動(dòng)程序訪問(wèn) I/O 外設(shè)。

查看 Linux 的 buff/cache:

$ free -mh
total used free shared buff/cache available
Mem: 7.6G 4.2G 2.9G 10M 547M 3.1G
Swap: 4.0G 0B 4.0G

實(shí)際上,Cache(緩存)和 Buffer(緩沖)從嚴(yán)格意義上講是 2 個(gè)不同的概念,Cache 側(cè)重加速 “讀”,而 Buffer 側(cè)重緩沖 “寫(xiě)”。但在很多場(chǎng)景中,由于讀寫(xiě)總是成對(duì)存在的,所以并沒(méi)有嚴(yán)格區(qū)分兩者,而是使用 buff/cache 來(lái)統(tǒng)一描述。

Page Cache

圖片

Page Cache(頁(yè)緩存)是最常用的 I/O Cache 技術(shù),以頁(yè)為單位的,內(nèi)容就是磁盤(pán)上的物理塊,用于減少 Application 對(duì) Storage 的 I/O 操作,能夠令 Application 對(duì)文件進(jìn)行順序讀寫(xiě)的速度接近于對(duì)內(nèi)存的讀寫(xiě)速度。

頁(yè)緩存讀策略:當(dāng) Application 發(fā)起一個(gè) Read() 操作,Kernel 首先會(huì)檢查需要的數(shù)據(jù)是否在 Page Cache 中:

  • 如果在,則直接從 Page Cache 中讀取。
  • 如果不在,則按照原 I/O 路徑從磁盤(pán)中讀取。同時(shí),還會(huì)根據(jù)局部性原理,進(jìn)行文件預(yù)讀,即:將已讀數(shù)據(jù)隨后的少數(shù)幾個(gè)頁(yè)面(通常是三個(gè))一同緩存到 Page Cache 中。

頁(yè)緩存寫(xiě)策略:當(dāng) Application 發(fā)起一個(gè) write() 操作,Kernel 首先會(huì)將數(shù)據(jù)寫(xiě)到 Page Cache,然后方法返回,即:Write back(寫(xiě)回)機(jī)制,區(qū)別于 Write Through(寫(xiě)穿)。此時(shí)數(shù)據(jù)還沒(méi)有真正的寫(xiě)入到文件中去,Kernel 僅僅將已寫(xiě)入到 Page Cache 的這一個(gè)頁(yè)面標(biāo)記為 “臟頁(yè)(Dirty Page)”,并加入到臟頁(yè)鏈表中。然后,由 flusher(pdflush,Page Dirty Flush)kernel thread(回寫(xiě)內(nèi)核線程)周期性地將臟頁(yè)鏈表中的頁(yè)寫(xiě)到磁盤(pán),并清理 “臟頁(yè)” 標(biāo)識(shí)。在以下 3 種情況下,臟頁(yè)會(huì)被寫(xiě)回磁盤(pán):

  1. 當(dāng)空閑內(nèi)存低于一個(gè)特定的閾值時(shí),內(nèi)核必須將臟頁(yè)寫(xiě)回磁盤(pán),以便釋放內(nèi)存。
  2. 當(dāng)臟頁(yè)在內(nèi)存中駐留時(shí)間超過(guò)一個(gè)特定的閾值時(shí),內(nèi)核必須將超時(shí)的臟頁(yè)寫(xiě)回磁盤(pán)。
  3. 當(dāng) Application 主動(dòng)調(diào)用 sync、fsync、fdatasync 等 SCI 時(shí),內(nèi)核會(huì)執(zhí)行相應(yīng)的寫(xiě)回操作。

flusher 刷新策略由以下幾個(gè)內(nèi)核參數(shù)決定(數(shù)值單位均為 1/100 秒):

# flush 每隔 5 秒執(zhí)行一次
$ sysctl vm.dirty_writeback_centisecs
vm.dirty_writeback_centisecs = 500

# 內(nèi)存中駐留 30 秒以上的臟數(shù)據(jù)將由 flush 在下一次執(zhí)行時(shí)寫(xiě)入磁盤(pán)
$ sysctl vm.dirty_expire_centisecs
vm.dirty_expire_centisecs = 3000

# 若臟頁(yè)占總物理內(nèi)存 10% 以上,則觸發(fā) flush 把臟數(shù)據(jù)寫(xiě)回磁盤(pán)
$ sysctl vm.dirty_background_ratio
vm.dirty_background_ratio = 10

綜上可見(jiàn),Page Cache 技術(shù)在理想的情況下,可以在一次 Storage I/O 的流程中,減少 2 次 DMA Copy 操作(不直接訪問(wèn)磁盤(pán))。

圖片

Buffered I/O

下圖展示了一個(gè) C 程序通過(guò) stdio 庫(kù)中的 printf() 或 fputc() 等輸出函數(shù)來(lái)執(zhí)行數(shù)據(jù)寫(xiě)入的操作處理流程。過(guò)程中涉及到了多處 I/O Buffer 的實(shí)現(xiàn):

  1. stdio buffer:在 Userspace 實(shí)現(xiàn)的 Buffer,因?yàn)?SCI 的成本昂貴,所以,Userspace Buffer 用于 “積累“ 到更多的待寫(xiě)入數(shù)據(jù),然后再通過(guò)一次 SCI 來(lái)完成真正的寫(xiě)入。另外,stdio 也支持 fflush() 強(qiáng)制刷新函數(shù)。
  2. Kernel buffer cache:處理包括上文以及提到的 Page Cache 技術(shù)之外,磁盤(pán)設(shè)備驅(qū)動(dòng)程序也提供塊級(jí)別的 Buffer 技術(shù),用于 “積累“ 更多的文件系統(tǒng)元數(shù)據(jù)和磁盤(pán)塊數(shù)據(jù),然后在合適的時(shí)機(jī)完成真正的寫(xiě)入。

圖片

零拷貝技術(shù)(Zero-Copy)

零拷貝技術(shù)(Zero-Copy),是通過(guò)盡量避免在 I/O 處理流程中使用 CPU Copy 和 DMA Copy 的技術(shù)。實(shí)際上,零拷貝并非真正做到了沒(méi)有任何拷貝動(dòng)作,它更多是一種優(yōu)化的思想。

下列表格從 CPU Copy 次數(shù)、DMA Copy 次數(shù)以及 SCI 次數(shù)這 3 個(gè)方面來(lái)對(duì)比了幾種常見(jiàn)的零拷貝技術(shù)??梢钥匆?jiàn),2 次 DMA Copy 是不可避免的,因?yàn)?DMA 是外設(shè) I/O 的基本行為。零拷貝技術(shù)主要從減少 CPU Copy 和 CPU 模式切換這 2 個(gè)方面展開(kāi)。

圖片

1、Userspace Direct I/O

Userspace Direct I/O(用戶(hù)態(tài)直接 I/O)技術(shù)的底層原理由 Kernel space 中的 ZONE_DMA 支持。ZONE_DMA 是一塊 Kernel 和 User Process 都可以直接訪問(wèn)的 I/O 外設(shè) DMA 物理內(nèi)存空間?;诖?, Application 可以直接讀寫(xiě) I/O 外設(shè),而 Kernel 只會(huì)輔助執(zhí)行必要的虛擬存儲(chǔ)配置工作,不直接參與數(shù)據(jù)傳輸。因此,該技術(shù)可以減少 2 次 CPU Copy。

Userspace Direct I/O 的缺點(diǎn):

  1. 由于旁路了 要求 Kernel buffer cache 優(yōu)化,就需要 Application 自身實(shí)現(xiàn) Buffer Cache 機(jī)制,稱(chēng)為自緩存應(yīng)用程序,例如:數(shù)據(jù)庫(kù)管理系統(tǒng)。
  2. 由于 Application 直接訪問(wèn) I/O 外設(shè),會(huì)導(dǎo)致 CPU 阻塞,浪費(fèi) CPU 資源,這個(gè)問(wèn)題需要結(jié)合異步 I/O 技術(shù)來(lái)規(guī)避。

圖片

具體流程看下圖:Using Direct I/O with DMA

圖片

2、mmap() + write()

mmap() SCI 用于將 I/O 外設(shè)(e.g. 磁盤(pán))中的一個(gè)文件、或一段內(nèi)存空間(e.g. Kernel Buffer Cache)直接映射到 User Process 虛擬地址空間中的 Memory Mapping Segment,然后 User Process 就可以通過(guò)指針的方式來(lái)直接訪問(wèn)這一段內(nèi)存,而不必再調(diào)用傳統(tǒng)的 read() / write() SCI。

圖片

申請(qǐng)空間函數(shù)原型:

  • addr 參數(shù):分配 MMS 映射區(qū)的入口地址,由 Kernel 指定,調(diào)用時(shí)傳入 NULL。
  • length 參數(shù):指示 MMS 映射區(qū)的大小。
  • prot 參數(shù):指示 MMS 映射區(qū)的權(quán)限,可選:PROT_READ、PROT_WRITE、PROT_READ|PROT_WRITE 類(lèi)型。
  • flags 參數(shù):標(biāo)志位參數(shù),可選:
  • MAP_SHARED:映射區(qū)所做的修改會(huì)反映到物理設(shè)備(磁盤(pán))上。
  • MAP_PRIVATE:映射區(qū)所做的修改不會(huì)反映到物理設(shè)備上。
  • fd 參數(shù):指示 MMS 映射區(qū)的文件描述符。
  • offset 參數(shù):指示映射文件的偏移量,為 4k 的整數(shù)倍,可以映射整個(gè)文件,也可以只映射一部分內(nèi)容。
  • 函數(shù)返回值:
  • 成功:更新 addr 入口地址。
  • 失?。焊?MAP_FAILED 宏。
void *mmap(void *adrr, size_t length, int prot, int flags, int fd, off_t offset);

釋放空間函數(shù)原型:

  • addr 參數(shù):分配 MMS 映射區(qū)的入口地址,由 Kernel 指定,調(diào)用時(shí)傳入 NULL。
  • length 參數(shù):指示 MMS 映射區(qū)的大小。
  • 函數(shù)返回值:
  • 成功:返回 0。
  • 失?。悍祷?-1。
int munmap(void *addr, size_t length)

圖片

可見(jiàn),mmap() 是一種高效的 I/O 方式。通過(guò) mmap() 和 write() 結(jié)合的方式,可以實(shí)現(xiàn)一定程度的零拷貝優(yōu)化。

// 讀
buf = mmap(diskfd, len);
// 寫(xiě)
write(sockfd, buf, len);

mmap() + write() 的 I/O 處理流程如下。

mmap() 映射:

  1. Application 發(fā)起 mmap() 調(diào)用,進(jìn)行文件操作,CPU 模式從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. mmap() 將指定的 Kernel Buffer Cache 空間映射到 Application 虛擬地址空間。
  3. mmap() 返回,CPU 模式從內(nèi)核態(tài)切換到用戶(hù)態(tài)。
  4. 在 Application 后續(xù)的文件訪問(wèn)中,如果出現(xiàn) Page Cache Miss,則觸發(fā)缺頁(yè)異常,并執(zhí)行 Page Cache 機(jī)制。通過(guò)已經(jīng)建立好的映射關(guān)系,只使用一次 DMA Copy 就將文件數(shù)據(jù)從磁盤(pán)拷貝到 Application User Buffer 中。

write() 寫(xiě)入:

  1. Application 發(fā)起 write() 調(diào)用,CPU 模式從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. 由于此時(shí) Application User Buffer 和 Kernel Buffer Cache 的數(shù)據(jù)是一致的,所以直接從 Kernel Buffer Cache 中 CPU Copy 到 Kernel Socket Buffer,并最終從 NIC 發(fā)出。
  3. write() 返回,CPU 模式從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

可見(jiàn),mmap() + write() 的 I/O 處理流程減少了一次 CPU Copy,但沒(méi)有減少 CPU 模式切換的次數(shù)。另外,由于 mmap() 的進(jìn)程間共享特性,非常適用于共享大文件的 I/O 場(chǎng)景。

mmap() + write() 的缺點(diǎn):當(dāng) mmap 映射一個(gè)文件時(shí),如果這個(gè)文件被另一個(gè)進(jìn)程所截獲,那么 write 系統(tǒng)調(diào)用會(huì)因?yàn)樵L問(wèn)非法地址被 SIGBUS 信號(hào)終止,SIGBUS 默認(rèn)會(huì)殺死進(jìn)程并產(chǎn)生一個(gè) coredump。解決這個(gè)問(wèn)題通常需要使用文件租借鎖實(shí)現(xiàn)。在 mmap 之前加鎖,操作完之后解鎖。即:首先為文件申請(qǐng)一個(gè)租借鎖,當(dāng)其他進(jìn)程想要截?cái)噙@個(gè)文件時(shí),內(nèi)核會(huì)發(fā)送一個(gè)實(shí)時(shí)的 RT_SIGNAL_LEASE 信號(hào),告訴當(dāng)前進(jìn)程有進(jìn)程在試圖破壞文件,這樣 write 在被 SIGBUS 殺死之前,會(huì)被中斷,返回已經(jīng)寫(xiě)入的字節(jié)數(shù),并設(shè)置 errno 為 success。

圖片

3、sendfile()

Linux Kernel 從 v2.1 開(kāi)始引入了 sendfile(),用于在 Kernel space 中將一個(gè) in_fd 的內(nèi)容復(fù)制到另一個(gè) out_fd 中,數(shù)據(jù)無(wú)需經(jīng)過(guò) Userspace,所以應(yīng)用在 I/O 流程中,可以減少一次 CPU Copy。同時(shí),sendfile() 比 mmap() 方式更具安全性。

函數(shù)原型:

  • out_fd 參數(shù):目標(biāo)文件描述符,數(shù)據(jù)輸入文件。
  • in_fd 參數(shù):源文件描述符,數(shù)據(jù)輸出文件。該文件必須是可以 mmap 的。
  • offset 參數(shù):指定從源文件的哪個(gè)位置開(kāi)始讀取數(shù)據(jù),若不需要指定,傳遞一個(gè) NULL。
  • count 參數(shù):指定要發(fā)送的數(shù)據(jù)字節(jié)數(shù)。
  • 函數(shù)返回值:
  • 成功:返回復(fù)制的字節(jié)數(shù)。
  • 失?。悍祷?-1,并設(shè)置 errno 全局變量來(lái)指示錯(cuò)誤類(lèi)型。
#include

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

sendfile() 處理流程:

  1. Application 調(diào)用 sendfile(),CPU 從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. Kernel 將數(shù)據(jù)通過(guò) DMA Copy 從磁盤(pán)設(shè)備寫(xiě)入 Kernel Buffer Cache。
  3. Kernel 將數(shù)據(jù)從 Kernel Buffer Cache 中 CPU Copy 到 Kernel Socket Buffer。
  4. Kernel 將數(shù)據(jù)從 Kernel Socket Buffer 中 DMA Copy 到 I/O 網(wǎng)卡設(shè)備。
  5. sendfile() 返回,CPU 從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

圖片

4、sendfile() + DMA Gather Copy

上文知道 sendfile() 還具有一次 CPU Copy,通過(guò)結(jié)合 DMA Gather Copy 技術(shù),可以進(jìn)一步優(yōu)化它。

DMA Gather Copy 技術(shù),底層有 I/O 外設(shè)的 DMA Controller 提供的 Gather 功能支撐,所以又稱(chēng)為 “DMA 硬件輔助的 sendfile()“。借助硬件設(shè)備的幫助,在數(shù)據(jù)從 Kernel Buffer Cache 到 Kernel Socket Buffer 之間,并不會(huì)真正的數(shù)據(jù)拷貝,而是僅拷貝了緩沖區(qū)描述符(fd + size)。待完成后,DMA Controller,可以根據(jù)這些緩沖區(qū)描述符找到依舊存儲(chǔ)在 Kernel Buffer Cache 中的數(shù)據(jù),并進(jìn)行 DMA Copy。

顯然,DMA Gather Copy 技術(shù)依舊是 ZONE_DMA 物理內(nèi)存空間共享性的一個(gè)應(yīng)用場(chǎng)景。

sendfile() + DMA Gather Copy 的處理流程:

  1. Application 調(diào)用 sendfile(),CPU 從用戶(hù)態(tài)切換到內(nèi)核態(tài)模式。
  2. Kernel 將數(shù)據(jù)通過(guò) DMA Copy 從磁盤(pán)設(shè)備寫(xiě)入 Kernel Buffer Cache。
  3. Kernel 將數(shù)據(jù)的緩沖區(qū)描述符從 Kernel Buffer Cache 中 CPU Copy 到 Kernel Socket Buffer(幾乎不費(fèi)資源)。
  4. 基于緩沖區(qū)描述符,CPU 利用 DMA Controller 的 Gather / Scatter 操作直接批量地將數(shù)據(jù)從 Kernel Buffer Cache 中 DMA Copy 到網(wǎng)卡設(shè)備。
  5. sendfile() 返回,CPU 從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

圖片

5、splice()

splice() 與 sendfile() 的處理流程類(lèi)似,但數(shù)據(jù)傳輸方式有本質(zhì)不同。

  • sendfile() 的傳輸方式是 CPU Copy,且具有數(shù)據(jù)大小限制;
  • splice() 的傳輸方式是 Pipeline,打破了數(shù)據(jù)范圍的限制。但也要求 2 個(gè) fd 中至少有一個(gè)必須是管道設(shè)備類(lèi)型。

函數(shù)原型:

  • fd_in 參數(shù):源文件描述符,數(shù)據(jù)輸出文件。
  • off_in 參數(shù):輸出偏移量指針,表示從源文件描述符的哪個(gè)位置開(kāi)始讀取數(shù)據(jù)。
  • fd_out 參數(shù):目標(biāo)文件描述符,數(shù)據(jù)輸入文件。
  • off_out 參數(shù):輸入偏移量指針,表示從目標(biāo)文件描述符的哪個(gè)位置開(kāi)始寫(xiě)入數(shù)據(jù)。
  • len 參數(shù):指示要傳輸?shù)臄?shù)據(jù)長(zhǎng)度。
  • flags:控制數(shù)據(jù)傳輸?shù)男袨榈臉?biāo)志位。
#define _GNU_SOURCE /* See feature_test_macros(7) */

#include

ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

splice() 的處理流程如下:

  1. Application 調(diào)用 splice(),CPU 從用戶(hù)態(tài)切換到內(nèi)核態(tài)。
  2. Kernel 將數(shù)據(jù)通過(guò) DMA Copy 從磁盤(pán)設(shè)備寫(xiě)入 Kernel Buffer Cache。
  3. Kernel 在 Kernel Buffer Cache 和 Kernel Socket Buffer 之間建立 Pipeline 傳輸。
  4. Kernel 將數(shù)據(jù)從 Kernel Socket Buffer 中 DMA Copy 到 I/O 網(wǎng)卡設(shè)備。
  5. splice() 返回,CPU 從內(nèi)核態(tài)切換到用戶(hù)態(tài)。

圖片

6、緩沖區(qū)共享技術(shù)

緩沖區(qū)共享技術(shù),是對(duì) Linux I/O 的一種顛覆,所以往往需要由 Application 和設(shè)備來(lái)共同實(shí)現(xiàn)。

其核心思想是:每個(gè) Applications 都維護(hù)著一個(gè) Buffer Pool,并且這個(gè) Buffer Pool 可以同時(shí)映射到 Kernel 虛擬地址空間,這樣 Userspace 和 Kernel space 就擁有了一塊共享的空間。以此來(lái)規(guī)避掉 CPU Copy 的行為。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    9525

    瀏覽量

    157077
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11764

    瀏覽量

    219094
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    9

    文章

    3212

    瀏覽量

    76384
  • 網(wǎng)絡(luò)通信
    +關(guān)注

    關(guān)注

    4

    文章

    840

    瀏覽量

    32572
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    LabVIEW的I/O接口設(shè)備驅(qū)動(dòng)

    虛擬儀器系統(tǒng)的硬件平臺(tái)由i/o接口設(shè)備和計(jì)算機(jī)構(gòu)成,為了能使計(jì)算機(jī)能夠?qū)?b class='flag-5'>i/o接口設(shè)備有效地進(jìn)行
    發(fā)表于 11-18 11:04 ?1.3w次閱讀
    LabVIEW的<b class='flag-5'>I</b>/<b class='flag-5'>O</b><b class='flag-5'>接口</b>設(shè)備驅(qū)動(dòng)

    PLC I/O接口的作用及選擇

    PLC作為一種工業(yè)控制計(jì)算機(jī),其控制對(duì)象是工業(yè)過(guò)程。它與工業(yè)生產(chǎn)過(guò)程的聯(lián)系就是通過(guò)輸入/輸出(I/O)接口實(shí)現(xiàn)的。I/O
    發(fā)表于 09-01 10:10 ?1.3w次閱讀

    Linux系統(tǒng)中網(wǎng)絡(luò)I/O性能改進(jìn)方法的研究

    選擇并設(shè)計(jì)高效的網(wǎng)絡(luò)I/O模型是改善服務(wù)器性能的關(guān)鍵。該文通過(guò)對(duì)Linux系統(tǒng)中幾種網(wǎng)絡(luò)I/O模型的分析和研究,提出3種改善網(wǎng)絡(luò)
    發(fā)表于 04-09 09:41 ?28次下載

    硬件在環(huán)(HIL)測(cè)試系統(tǒng)對(duì)I/O接口的選擇

     本教程討論了多種I/O接口選項(xiàng),能夠用于實(shí)時(shí)處理器創(chuàng)建您的硬件在環(huán)測(cè)試系統(tǒng)。 高性能模塊化的I/O
    發(fā)表于 06-19 08:27 ?4035次閱讀
    硬件在環(huán)(HIL)測(cè)試系統(tǒng)對(duì)<b class='flag-5'>I</b>/<b class='flag-5'>O</b><b class='flag-5'>接口</b>的選擇

    Linux 系統(tǒng)應(yīng)用編程之標(biāo)準(zhǔn)I/O詳解

    本章前面幾節(jié)所述的文件及I/O讀寫(xiě)都是基于文件描述符的。這些都是基本的I/O控制,是不帶緩存的。而本節(jié)所要討論的I/
    發(fā)表于 10-18 15:45 ?0次下載

    學(xué)會(huì)處理Linux內(nèi)核訪問(wèn)外設(shè)I/O資源的方式

    Linux內(nèi)核訪問(wèn)外設(shè)I/O內(nèi)存資源的方式有兩種:動(dòng)態(tài)映射(ioremap)和靜態(tài)映射(map_desc)。
    發(fā)表于 05-05 13:54 ?821次閱讀

    如何更改 LinuxI/O 調(diào)度器

    LinuxI/O 調(diào)度器是一個(gè)以塊式 I/O 訪問(wèn)存儲(chǔ)卷的進(jìn)程,有時(shí)也叫磁盤(pán)調(diào)度器。Linux
    發(fā)表于 05-15 15:54 ?1205次閱讀
    如何更改 <b class='flag-5'>Linux</b> 的 <b class='flag-5'>I</b>/<b class='flag-5'>O</b> 調(diào)度器

    Linux中如何使用信號(hào)驅(qū)動(dòng)式I/O

    一、Linux 的 5 種 IO 模型 二、如何使用信號(hào)驅(qū)動(dòng)式 I/O? 三、內(nèi)核何時(shí)會(huì)發(fā)送 “IO 就緒” 信號(hào)? 四、最簡(jiǎn)單的示例 五、擴(kuò)展知識(shí) 一、Linux 的 5 種 IO
    的頭像 發(fā)表于 03-12 14:47 ?3064次閱讀
    <b class='flag-5'>Linux</b>中如何使用信號(hào)驅(qū)動(dòng)式<b class='flag-5'>I</b>/<b class='flag-5'>O</b>?

    深入理解Linux傳統(tǒng)的System Call I/O

    傳統(tǒng)的 System Call I/OLinux 系統(tǒng)中,傳統(tǒng)的訪問(wèn)方式是通過(guò) write() 和 read() 兩個(gè)系統(tǒng)調(diào)用實(shí)現(xiàn)的,通過(guò) read() 函數(shù)讀取文件到到緩存區(qū)中,然后通過(guò)
    的頭像 發(fā)表于 11-19 09:52 ?2551次閱讀
    深入理解<b class='flag-5'>Linux</b>傳統(tǒng)的System Call <b class='flag-5'>I</b>/<b class='flag-5'>O</b>

    PLC系統(tǒng)的I/O接口該如何選擇

    作為一臺(tái)工業(yè)控制計(jì)算機(jī),plc控制著工業(yè)過(guò)程。它與工業(yè)生產(chǎn)過(guò)程的連接是通過(guò)輸入輸出接口實(shí)現(xiàn)的。輸入輸出接口是PLC與外界的接口。I/O
    發(fā)表于 01-17 09:48 ?4269次閱讀

    探究I/O虛擬化及Virtio接口技術(shù)(上)

    I/O虛擬化是SmartNIC/DPU/IPU中最核心的部分,AWS NITRO就是從I/O硬件虛擬化開(kāi)始,逐漸開(kāi)啟了DPU這個(gè)新處理
    的頭像 發(fā)表于 04-04 16:54 ?5208次閱讀
    探究<b class='flag-5'>I</b>/<b class='flag-5'>O</b>虛擬化及Virtio<b class='flag-5'>接口</b>技術(shù)(上)

    探究I/O虛擬化及Virtio接口技術(shù)(下)

    I/O虛擬化是SmartNIC/DPU/IPU中最核心的部分,AWS NITRO就是從I/O硬件虛擬化開(kāi)始,逐漸開(kāi)啟了DPU這個(gè)新處理
    的頭像 發(fā)表于 04-04 17:03 ?4027次閱讀
    探究<b class='flag-5'>I</b>/<b class='flag-5'>O</b>虛擬化及Virtio<b class='flag-5'>接口</b>技術(shù)(下)

    Linux系統(tǒng)下I/O操作講解

    Linux系統(tǒng)下I/O 一、I/O簡(jiǎn)介 I/O(輸入
    的頭像 發(fā)表于 11-08 15:13 ?2435次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)下<b class='flag-5'>I</b>/<b class='flag-5'>O</b>操作講解

    I/O接口I/O端口的區(qū)別

    在計(jì)算機(jī)系統(tǒng)中,I/O接口I/O端口是實(shí)現(xiàn)CPU與外部設(shè)備數(shù)據(jù)交換的關(guān)鍵組件,它們?cè)诠δ堋⒔Y(jié)構(gòu)、作用及運(yùn)作機(jī)制上均存在顯著差異,卻又相互協(xié)
    的頭像 發(fā)表于 02-02 16:00 ?3614次閱讀

    工業(yè)網(wǎng)關(guān)的IO接口有哪些類(lèi)型

    工業(yè)網(wǎng)關(guān)的I/O接口類(lèi)型多樣,主要分為數(shù)字I/O、模擬I/O
    的頭像 發(fā)表于 12-02 09:27 ?551次閱讀