file.flush () ของ Python กำลังทำอะไรอยู่


143

ฉันพบสิ่งนี้ในเอกสาร Python สำหรับ File Objects :

flush () ไม่จำเป็นต้องเขียนข้อมูลของไฟล์ลงในดิสก์ ใช้ flush () ตามด้วย os.fsync () เพื่อให้แน่ใจว่าพฤติกรรมนี้

คำถามของฉันคือ Python flushกำลังทำอะไรอยู่? ฉันคิดว่ามันบังคับให้เขียนข้อมูลลงในดิสก์ แต่ตอนนี้ฉันเห็นว่ามันไม่ ทำไม?

คำตอบ:


227

โดยทั่วไปจะมีการบัฟเฟอร์สองระดับที่เกี่ยวข้อง:

  1. บัฟเฟอร์ภายใน
  2. บัฟเฟอร์ของระบบปฏิบัติการ

บัฟเฟอร์ภายในคือบัฟเฟอร์ที่สร้างขึ้นโดยรันไทม์ / ไลบรารี / ภาษาที่คุณกำลังเขียนโปรแกรมและมีขึ้นเพื่อเร่งความเร็วโดยหลีกเลี่ยงการเรียกใช้ระบบสำหรับการเขียนทุกครั้ง แต่เมื่อคุณเขียนลงในไฟล์อ็อบเจ็กต์คุณจะเขียนลงในบัฟเฟอร์และเมื่อใดก็ตามที่บัฟเฟอร์เต็มข้อมูลจะถูกเขียนไปยังไฟล์จริงโดยใช้การเรียกระบบ

แต่เนื่องจากบัฟเฟอร์ระบบปฏิบัติการนี้อาจจะไม่ได้หมายความว่าข้อมูลจะถูกเขียนไปยังดิสก์ อาจหมายความว่าข้อมูลถูกคัดลอกจากบัฟเฟอร์ที่รันไทม์ของคุณดูแลไปยังบัฟเฟอร์ที่ระบบปฏิบัติการดูแล

หากคุณเขียนบางอย่างและลงท้ายด้วยบัฟเฟอร์ (เท่านั้น) และไฟถูกตัดไปที่เครื่องของคุณข้อมูลนั้นจะไม่อยู่ในดิสก์เมื่อเครื่องปิด

ดังนั้นเพื่อช่วยในการที่คุณมีflushและfsyncวิธีการในวัตถุที่เกี่ยวข้อง

ขั้นแรกflushจะเขียนข้อมูลใด ๆ ที่แฝงอยู่ในบัฟเฟอร์โปรแกรมไปยังไฟล์จริง โดยทั่วไปหมายความว่าข้อมูลจะถูกคัดลอกจากบัฟเฟอร์โปรแกรมไปยังบัฟเฟอร์ของระบบปฏิบัติการ

โดยเฉพาะสิ่งนี้หมายความว่าหากกระบวนการอื่นเปิดไฟล์เดียวกันเพื่ออ่านมันจะสามารถเข้าถึงข้อมูลที่คุณเพิ่งล้างไปยังไฟล์ได้ อย่างไรก็ตามไม่ได้หมายความว่าจะถูกเก็บไว้ในดิสก์อย่างถาวร

ในการทำเช่นนั้นคุณต้องเรียกใช้os.fsyncวิธีการที่ทำให้แน่ใจว่าบัฟเฟอร์ของระบบปฏิบัติการทั้งหมดจะซิงโครไนซ์กับอุปกรณ์จัดเก็บข้อมูลที่พวกเขาใช้กล่าวคือวิธีการนั้นจะคัดลอกข้อมูลจากบัฟเฟอร์ของระบบปฏิบัติการไปยังดิสก์

โดยปกติคุณไม่จำเป็นต้องกังวลกับวิธีใดวิธีหนึ่ง แต่ถ้าคุณอยู่ในสถานการณ์ที่ความหวาดระแวงเกี่ยวกับสิ่งที่เกิดขึ้นจริงบนดิสก์เป็นสิ่งที่ดีคุณควรโทรทั้งสองครั้งตามคำแนะนำ


ภาคผนวกในปี 2561

โปรดทราบว่าดิสก์ที่มีกลไกแคชนั้นพบได้บ่อยกว่าในปี 2013 ดังนั้นในตอนนี้จึงมีระดับการแคชและบัฟเฟอร์ที่เกี่ยวข้องมากขึ้น ฉันคิดว่าบัฟเฟอร์เหล่านี้จะถูกจัดการโดยการโทรซิงค์ / ล้างเช่นกัน แต่ฉันไม่รู้จริงๆ


10
เมื่อฉันใช้with file('blah') as fd: #dostuffโครงสร้างฉันรู้ว่ามันรับประกันการปิดตัวอธิบายไฟล์ มันล้างหรือซิงค์ด้วย?
Marcin

3
@ Marcin: มันวาบ แต่ไม่ซิงค์
Alex I

8
fsyncเป็นสิ่งจำเป็นสำหรับปรมาณู คุณไม่สามารถคาดหวังว่าจะปิดไฟล์เปิดใหม่และค้นหาเนื้อหาของคุณโดยไม่มีfsyncตรงกลาง มักใช้งานได้ แต่ไม่สามารถใช้งานได้บน linux ที่มี ext4 และตัวเลือกการติดตั้งเริ่มต้น นอกจากนี้ยังfsyncไม่รับประกันว่าจะทำให้เตารีดพลิกบนจานด้วยแม่เหล็กจริงๆเนื่องจาก 1: fsync สามารถปิดใช้งานได้ (โดยโหมดแล็ปท็อป) และ 2: การบัฟเฟอร์ภายในฮาร์ดดิสก์อาจไม่ได้รับคำสั่งให้ล้าง
v.oddou

1
มีวิธีใดบ้างในการล้างบัฟเฟอร์ของระบบปฏิบัติการสำหรับไฟล์ทั้งหมดหากไฟล์ถูกเขียนโดยกระบวนการอื่น
Nacht

1
fsync ค่อนข้างแพง โดยทั่วไปคุณไม่ได้เขียนซอฟต์แวร์ที่มีความสำคัญต่อภารกิจที่ต้องการความสอดคล้องกับ ACID 100% และความทนทานสำหรับการเข้าถึงดิสก์และถ้าคุณทำคุณอาจตระหนักถึงเรื่องนี้อย่างเจ็บปวดและควรตระหนักถึงขั้นตอนที่คุณสามารถทำได้เพื่อรับการค้ำประกันเหล่านี้ . การเรียก fsync จะรอให้มีการเข้าถึงฟิสิคัลดิสก์เพื่อเขียนข้อมูลลงดิสก์ในขณะที่การล้างและการปิดจะรอให้ข้อมูลถูกย้ายไปยังหน่วยความจำแคชเท่านั้น ความแตกต่างของความเร็วอาจเป็นคำสั่งขนาดหลายขนาด
Lasse V.Karlsen

10

เนื่องจากระบบปฏิบัติการอาจไม่ทำเช่นนั้น การดำเนินการล้างจะบังคับให้ข้อมูลไฟล์อยู่ในแคชไฟล์ใน RAM และจากนั้นระบบปฏิบัติการจะส่งข้อมูลไปยังดิสก์


6
คุณพูดถูก แต่actuallyมีความสัมพันธ์กับที่นี่: หากอุปกรณ์เป้าหมายเปิดใช้งานการเขียนแคชข้อมูลอาจไม่ถึงจาน / ชิปจริงเมื่อos.fsync()ส่งคืน
Frédéric Hamidi

7

มันจะล้างบัฟเฟอร์ภายในซึ่งควรจะทำให้ระบบปฏิบัติการเขียนบัฟเฟอร์ไปยังไฟล์ [1] Python ใช้การบัฟเฟอร์เริ่มต้นของระบบปฏิบัติการเว้นแต่คุณจะกำหนดค่าเป็นอย่างอื่น

แต่บางครั้ง OS ก็ยังเลือกที่จะไม่ให้ความร่วมมือ โดยเฉพาะอย่างยิ่งกับสิ่งที่ยอดเยี่ยมเช่นความล่าช้าในการเขียนใน Windows / NTFS โดยทั่วไปแล้วบัฟเฟอร์ภายในจะถูกล้างออก แต่บัฟเฟอร์ของระบบปฏิบัติการยังคงยึดอยู่ ดังนั้นคุณต้องบอก OS ให้เขียนลงดิสก์ด้วยos.fsync()ในกรณีเหล่านั้น

[1] http://docs.python.org/library/stdtypes.html


0

โดยทั่วไปแล้ว flush () จะล้างบัฟเฟอร์ RAM ของคุณพลังที่แท้จริงของมันคือช่วยให้คุณสามารถเขียนต่อได้ในภายหลัง - แต่ไม่ควรคิดว่าเป็นคุณสมบัติการเขียนลงไฟล์ที่ดีที่สุด / ปลอดภัยที่สุด เป็นการล้าง RAM ของคุณเพื่อให้มีข้อมูลมากขึ้นนั่นคือทั้งหมด หากคุณต้องการให้แน่ใจว่าข้อมูลถูกเขียนลงในไฟล์อย่างปลอดภัยให้ใช้ close () แทน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.