Linux-- 重定向緩沖區

目錄

0.接上篇文章

1.粗略的見一下這兩個問題

2.理解重定向?

3.理解緩沖區?


0.接上篇文章

Linux--基礎IO(文件描述符fd)-CSDN博客

1.粗略的見一下這兩個問題

先來了解幾個函數:

?????????stat()函數用于獲取指定文件或符號鏈接的元數據。如果文件是一個符號鏈接,stat()將返回該符號鏈接本身的元數據,而不是它所指向的目標文件的元數據。

? ?fstat()函數用于獲取已打開文件的元數據。它通常用于在文件描述符已經打開之后獲取文件的元數據。

? ?lstat()函數與stat()函數類似,但它專門用于獲取符號鏈接的元數據。如果指定的文件是一個符號鏈接,lstat()將返回該符號鏈接本身的元數據,而不是它所指向的目標文件的元數據。

  • fd:一個已打開的文件描述符。
  • buf:一個指向struct stat的指針,用于存儲符號鏈接的元數據。
  • path:要檢查的文件或目錄的路徑。

????????這三個函數都使用struct stat結構來存儲文件的元數據。這個結構包含了許多字段,如文件類型(普通文件、目錄、符號鏈接等)、權限、所有者ID、組ID、大小、時間戳等。具體的字段取決于你的系統和編譯器,但你可以查閱sys/stat.h頭文件以獲取更多詳細信息。

演示:


再來看一段代碼:

????????我們打開文件的時候做了一個操作,colse(1)首先關閉了文件描述符?1,我們知道文件描述符1,表示的是顯示器文件,而printf&&fprintf都是向顯示器上打印的,現在關閉了顯示器文件,意味著顯示器上不會出現打印的內容。

????????文件描述符1被關閉了,意味著fd1空了出來,那么log.txt將繼承fd1(文件描述符分配規則;查自己的文件描述表,分配最小的沒有被使用的fd),那么現在向fd1中寫就是在向log.txt中寫,所以我們查看到log.txt中的內容就是printf&&fprintf輸出的內容,這就是對文件做重定向重定向的本質:是在內核中改變文件描述符表特定下標的內容,和上層無關!)

在這段代碼中:我們還需要注意一點,fflush(stdout)刷新stdout,如果不進行此操作,log.txt中是不會有任何內容的,這是為什么呢?

原因是:在struct FILE*這個結構體中存在語言級別的緩沖區,我們在使用printf&&fprintf時,并不是直接通過文件描述符寫入到內核文件緩沖區中,而是先寫到語言級別的緩存區中,再由C語言通過文件描述符,刷新到內核文件緩存區當中,此時外設才能看到輸出的內容,因此fflush(stdout)此時的工作是將stdout緩沖區中的內容通過文件描述符1,刷新到log.txt內核文件緩存區當中去,這時候log.txt中才能看到內容。如果沒有close(fd)這一語句,那么不加刷新也沒關系,進程結束之后,會自動通過fd刷新到文件中。


2.理解重定向?

先認識一個系統調用接口:dup2

??dup2?的功能是將一個已存在的文件描述符復制到另一個文件描述符,如果目標文件描述符已經打開,則先將其關閉。(本質是文件描述符下標所對應內容的拷貝)

#include <unistd.h>  int dup2(int oldfd, int newfd);

1. 標準輸出重定向,由顯示器打印->log.txt打印(接上面例子,我們使用dup2系統調用接口該如何做呢?)

????????也就是我們沒有關閉fd1,那么新打開的log.txt的fd就是3,我們使用了dup2的效果就是,把fd3的內容拷貝給了fd1,也就是說,讓fd1指向了文件log.txt,所以未來向fd1里寫入內容,實際上就是向log.txt中寫入內容,最終只會留下fd3(oldfd)。(fd1和fd3里的地址一樣l)

那么代碼就應該這么寫:

這樣輸出到顯示器的內容就輸出到log.txt了


3.理解緩沖區?

在Linux操作系統中,緩沖區是一個非常重要的概念,主要用于提高I/O(輸入/輸出)操作的效率。以下是關于Linux操作系統中緩沖區的理解:

  1. 概念:緩沖區是內存中的一塊區域,用于臨時存放數據。當進程需要向外部設備(如磁盤、網絡等)寫入數據時,它不會直接將數據寫入設備,而是先將數據寫入到緩沖區中。同樣,當進程從外部設備讀取數據時,數據也是先從設備讀取到緩沖區,當緩沖區的數據到達某個值的時候,在統一的刷新到進程中。
  2. 作用
    • 減少對外部設備的直接訪問次數,從而降低I/O操作的開銷。
    • 允許進程進行批量數據傳輸,從而提高數據傳輸的效率。
    • 通過緩存數據,可以實現對數據的預處理和后處理,如數據壓縮、加密等。
  3. 刷新策略:Linux中的緩沖區有不同的刷新策略,以適應不同的應用場景。
    • 無緩沖:數據一寫入到緩沖區就立即刷新到外部設備。(eg:1.語言級的緩沖區printf/fprintf,2.系統調用fsync)
    • 行緩沖:當在輸入或輸出中遇到換行符(\n)時,緩沖區會刷新一次。這種策略常用于與終端設備(如顯示器)的交互。
    • 全緩沖:當緩沖區滿時,數據才會被刷新到外部設備。這種策略常用于寫入磁盤文件等場景。
    • 特殊情況(1.進程退出,自動刷新;2強制刷新)
  4. 與文件系統的關系:在Linux文件系統中,緩沖區也起著重要的作用。當應用程序讀取文件時,內核會將文件數據讀入內核空間緩沖區中,然后再將數據從內核空間緩沖區復制到用戶空間緩沖區中。同樣地,當應用程序向文件寫入數據時,數據也是先寫入到用戶空間緩沖區中,然后再由內核將數據從用戶空間緩沖區復制到內核空間緩沖區,并最終寫入到磁盤上。
  5. 緩沖區就在struct FILE*結構體中,每一個文件都有自己的緩沖區(這是在語言層面的)

補充示例

????????刷新策略發生改變,看下面的兩段代碼:

第一段代碼及它的運行結果(我們將打印到屏幕的內容重定向到文件中)

第二段代碼及它的運行結果(與第一段代碼不同的是,加入了一個fork函數)

問題:為什么加了fork之后,會打印兩次內容,fork不是只會繼承父進程下面的代碼嗎?為什么C語言庫函數的內容打印了兩次,而系統調用的只打印了一次呢?

????????首先./mytest這個操作是向顯示器文件打印,顯示器文件的刷新策略是行緩沖,現在轉為向普通文件打印,普通文件的刷新策略是全緩沖,由顯示器文件轉向普通文件打印,這里刷新策略就發生了改變此時printf/fprintf在執行完之后,緩沖區還沒有寫滿(因為是全緩沖),不做刷新,最后fork的時候就出現了父子進程,fork結束后進程就直接退出了,此時父子進程都要執行刷新,所以就打印了兩次內容,而系統調用接口是直接向內核級緩沖區中寫的,所以不存在刷新兩次的問題了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11362.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11362.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android 系統省電軟件分析

1、硬件耗電 主要有&#xff1a; 1、屏幕 2、CPU 3、WLAN 4、感應器 5、GPS(目前我們沒有) 電量其實是目前手持設備最寶貴的資源之一&#xff0c;大多數設備都需要不斷的充電來維持繼續使用。不幸的是&#xff0c;對于開發者來說&#xff0c;電量優化是他們最后才會考慮的的事情…

排序實現題目:排序數組

文章目錄 題目標題和出處難度題目描述要求示例數據范圍 前言冒泡排序原理示例代碼復雜度分析穩定性分析 選擇排序原理示例代碼復雜度分析穩定性分析 插入排序原理示例代碼復雜度分析穩定性分析 希爾排序原理示例代碼復雜度分析穩定性分析 歸并排序原理示例代碼復雜度分析穩定性…

Jackson如何禁止在反序列化字符串為對應java bean時,字符串中的null被反序列成為NullNode

直接說應用場景,json文件中有一個如下配置: [{"name":"John Doe","age":28,"jsonNode":null},{"name":"John1","age":31}] 待反序列化類定義如下所示: @Data static class TestClass {/*** 名字.*…

【C++】詳解STL的適配器容器之一:優先級隊列 priority_queue

目錄 堆算法 概述 向下調整建堆 向上調整建堆 建堆算法 仿函數 概述 使用介紹 emtpy size top push pop 模擬實現 仿函數 框架 向下調整算法 向上調整算法 pop push empty top 要理解優先級隊列&#xff0c;需要有如下知識 STL容器之一的vector&#xf…

聚類分析 | 基于GA遺傳算法優化kmeans聚類(Matlab)

聚類分析 | 基于GA遺傳算法優化kmeans聚類&#xff08;Matlab&#xff09; 目錄 聚類分析 | 基于GA遺傳算法優化kmeans聚類&#xff08;Matlab&#xff09;效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 GA-kmeans聚類算法&#xff0c;通過GA遺傳算法優化kmeans聚類&…

序列化的不同格式:JSON、XML、TOML、CSON、YAML

前言 這篇文章參考于知乎&#xff0c;進行了一些總結。 正文 首先什么是序列化&#xff0c;數據序列化是從一個系統獲取一些信息&#xff0c;將其轉換為其它系統可以讀取的格式&#xff0c;然后將其傳遞給其它系統的過程。也就是可以讓不同系統“通信”。 序列化需要滿足兩…

JetPack Compose Navigation

1. 導入依賴 implementation("androidx.navigation:navigation-compose:2.7.7") 2.kotlin編譯版本升級 composeOptions {kotlinCompilerExtensionVersion "1.5.0"} 3.插件版本升級 // Top-level build file where you can add configuration options c…

學習筆記:IEEE 1003.13-2003【POSIX PSE51接口列表】

一、POSIX PSE51接口列表 根據IEEE 1003.13-2003&#xff0c;整理了POSIX PSE51接口API&#xff08;一共286個&#xff09;&#xff0c;每個API支持鏈接查看。 IEEE POSIX接口online搜索鏈接&#xff1a; The Open Group Base Specifications Issue 7, 2018 edition 詳細內…

【python】模塊與包

Python中的模塊和包是組織和管理代碼的重要工具。通過模塊和包&#xff0c;你可以更好地管理和重用你的代碼&#xff0c;使得代碼更加模塊化和可維護。 目錄 前言 正文 一、模塊 1、模塊的分類 1&#xff09;內置模塊 python解釋器中默認擁有的模塊可以直接使用&#xff08;…

用戶需求甄別和篩選的6大標準

產品經理日常經常接收到大量的需求&#xff0c;并不是所有的需求都需要開發&#xff0c;需要進行甄別和篩選&#xff0c;這樣有利于確保項目的成功、優化資源利用以及提高產品質量。 那么針對這些用戶需求進行甄別或篩選的評判標準是什么&#xff1f;需求篩選可以說是初步的需求…

代碼隨想錄-算法訓練營day31【貪心算法01:理論基礎、分發餅干、擺動序列、最大子序和】

代碼隨想錄-035期-算法訓練營【博客筆記匯總表】-CSDN博客 第八章 貪心算法 part01● 理論基礎 ● 455.分發餅干 ● 376. 擺動序列 ● 53. 最大子序和 貪心算法其實就是沒有什么規律可言&#xff0c;所以大家了解貪心算法 就了解它沒有規律的本質就夠了。 不用花心思去研究其…

C++牛客周賽題目分享(2)小紅叕戰小紫,小紅的數組移動,小紅的素數合并,小紅的子序列求和

目錄 ?編輯 1.前言 2.四道題目 1.小紅叕戰小紫 1.題目描述 2.輸入描述 3.輸出描述 4.示例 5.題解與思路 2.小紅的數組移動 1.題目描述 2.輸入描述 3.輸出描述 4.示例 5.題解與思路 3.小紅的素數合并 1.題目描述 2.輸入描述 3.輸出描述 4.示例 5.題解與思…

增強For循環執行順序探究

增強For循環執行順序探究 增強For循環基礎執行順序探討對于數組對于集合 經典示例數組示例集合示例&#xff08;ArrayList&#xff09; 注意事項結論 在Java編程中&#xff0c;增強型for循環&#xff08;也稱為“foreach”循環&#xff09;是一種簡潔而強大的迭代集合或數組元素…

super

super 一、理解 super.屬性&#xff1a;在子類中&#xff0c;調用父類非私有化的成員屬性 super.方法&#xff1a;在子類中&#xff0c;調用父類非私有化的成員方法 super()&#xff1a;在子類構造方法中調用父類非私有的構造方法 二、案例 需求&#xff1a;編寫中國人和日本人…

云原生新手和開源教育分論壇 01-Kubernetes 社區:從新手到影響者

2024年04月20日 上海KCD & Shanghai&#xff1a;https://community.cncf.io/events/details/cncf-kcd-shanghai-presents-kcd-shanghai-2024/視頻觀看&#xff1a;https://www.bilibili.com/video/BV1nD421T786/?spm_id_from333.999.0.0&vd_sourceae7b192be069682aabc…

【FreeRTOS 快速入門】-- 1、STM32工程移植FreeRTOS

目錄 一、新建STM32工程 為了示范完整的移植過程&#xff0c;我們從0開始&#xff0c;新建一個標準的STM32點燈工程。 &#xff08;本篇以CubeMX作示范&#xff0c;CubeIDE操作近同&#xff0c;可作對比參考&#xff09; 1、新建工程 選擇 芯片型號 新建工程 2、搜索芯片型號…

24年做抖音小店,你還停留在數據?別人都已經開始注重利潤了

大家好&#xff0c;我是電商笨笨熊 一件事情持續做&#xff0c;一個項目持續深耕&#xff0c;意義到底是什么&#xff1f; 這句話我常常說&#xff0c;但很多人似乎走偏了實際意義&#xff1b; 尤其對于新手來說&#xff0c;做抖音小店總是向往某某老玩家多么牛的數據&#…

程序員健康指南:運動,讓代碼更流暢

程序員健康指南&#xff1a;運動&#xff0c;讓代碼更流暢 程序員&#xff0c;一個與電腦相伴的群體&#xff0c;長時間的久坐和高強度的腦力勞動是他們的日常。然而&#xff0c;久坐不僅影響體態&#xff0c;更對心臟健康構成威脅。根據《歐洲心臟雜志》的研究&#xff0c;中…

第十三節 huggingface的trainner解讀與Demo

文章目錄 前言一、trainer和TrainingArguments訓練與預測完整Demo1、數據構建2、TrainingArguments構建3、Trainer初始化4、模型訓練5、模型推理6、完整demo代碼7、完整運行結果二、輔助函數1、yield返回內容2、迭代器中斷恢復迭代demo3、yield from結構4、torch.Generator()的…

【PPT技巧】ppt文件打開就是只讀模式,如何改為可編輯模式?

PPT文檔打開是只讀模式&#xff0c;如何改成可編輯文檔呢&#xff1f;這需要分幾種情況來說&#xff0c;所以今天將介紹幾種方法幫助PPT只讀文檔改為可編輯文檔。 方法一&#xff1a; 我們可以先查看一下文件屬性&#xff0c;屬性中有只讀屬性&#xff0c;當我們打開文檔之后帶…