จะเกิดอะไรขึ้นเมื่อคุณอ่านไฟล์ในขณะที่เขียนทับ?


26

สมมติว่าฉันอ่าน (cat) ไฟล์ในขณะที่กระบวนการอื่นกำลังเขียนเนื้อหาใหม่ ผลผลิตสามารถคาดการณ์ได้หรือไม่ อะไรจะเกิดขึ้น?


3
พฤติกรรมไม่ได้กำหนดคุณไม่ควรทำเช่นนี้
เดซี่

คำตอบ:


19

ขึ้นอยู่กับสิ่งที่ผู้เขียนทำ

หากผู้เขียนเขียนทับไฟล์ที่มีอยู่แล้วผู้อ่านจะเห็นเนื้อหาใหม่เมื่อผู้เขียนเขียนทับผู้อ่านถ้าเคย หากผู้เขียนและผู้อ่านดำเนินการที่ความเร็วตัวแปรผู้อ่านอาจดูเนื้อหาเก่าและใหม่

หากผู้เขียนตัดไฟล์ก่อนที่จะเริ่มเขียนผู้อ่านจะทำงานต่อท้ายไฟล์ที่จุดนั้น

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

ระบบปฏิบัติการ Unix มีแนวโน้มที่จะไม่ให้มีผลบังคับใช้ล็อค หากแอปพลิเคชันต้องการตรวจสอบให้แน่ใจว่าส่วนประกอบนักเขียนและส่วนประกอบเครื่องอ่านไม่ได้อยู่ที่นิ้วเท้าของกันและกันมันก็ขึ้นอยู่กับผู้พัฒนาที่จะใช้การล็อคที่เหมาะสม มีข้อยกเว้นบางประการที่ไฟล์ที่เปิดโดยเคอร์เนลอาจได้รับการปกป้องจากการเขียนโดยแอปพลิเคชันผู้ใช้ตัวอย่างเช่นอิมเมจระบบไฟล์แบบวนรอบ -หรือการปฏิบัติการที่กำลังดำเนินการในตัวแปรยูนิกซ์บางตัว


Gilles คำอธิบายของคุณมีผลกับftp/ ในsftpสถานการณ์หรือไม่? สมมติว่ากระบวนการเริ่มอ่านftpไฟล์ที่ถูกส่งขณะที่ไฟล์เดียวกันเวอร์ชันอื่นกำลังเขียนทับไฟล์นั้นเนื่องจากการส่งใหม่
iruvar

@ 1_CR ใช่ ในกรณีนั้นผู้เขียนและผู้อ่านคือกระบวนการ ftpd
Gilles 'หยุดความชั่วร้าย'

ความหมายของการแซงที่นี่คืออะไร?
วิกเตอร์ Choy

@VictorChoy Standard ความหมาย: เพื่อเริ่มต้นหลัง / หลังจากคนอื่นและในบางจุดย้ายไปข้างหน้าของพวกเขา
Gilles 'หยุดความชั่วร้าย' ใน

18

มันเป็นเงื่อนไขการแข่งขันแบบคลาสสิกดังนั้นผลลัพธ์จึงไม่สามารถคาดการณ์ได้ตามคำจำกัดความ

ในหมู่คนอื่น ๆ มันขึ้นอยู่กับ

  • fopen(3)หรือopen(2)เขียนโหมด
  • อย่างไร / ถ้าผู้เขียนกำลังบัฟเฟอร์เอาต์พุตของมัน
  • ผู้อ่านอ่านไฟล์อย่างไร
  • ความแตกต่างความเร็วระหว่างผู้อ่านและนักเขียน
  • ความแตกต่างของเวลาระหว่างการอ่านและการเริ่มต้นของนักเขียน
  • และแน่นอนว่าในเครื่องมัลติคอร์ที่ทันสมัยสิ่งต่าง ๆ มีความซับซ้อนมากยิ่งขึ้นจากปัจจัยอื่น ๆ ที่ลดลง (เช่นการกำหนดตารางกระบวนการ)

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


1
คำตอบนี้ครอบคลุมกว่าของฉันมาก ลบคำตอบของฉัน
killermist

0

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

$ tail -f <filename>

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

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