สิ่งที่รับประกันสำหรับการเขียนพร้อมกันลงในท่อที่มีชื่อ?


32

ตัวอย่างเช่นฉันสร้างไปป์ที่มีชื่อดังต่อไปนี้:

mknod myPipe p

และฉันอ่านจากบางกระบวนการ (ตัวอย่างเช่นเซิร์ฟเวอร์บางตัว) สำหรับวัตถุประสงค์ตัวอย่างฉันใช้หาง:

tail -f myPipe

หากกระบวนการไคลเอนต์หลายแห่งเขียนข้อความลงไป (ตัวอย่างเช่นecho "msg" >> myPipeอาจมีโอกาสที่ข้อความจะถูกอินเตอร์ลีฟเช่นนี้:

 <beginning of message1><message2><ending of message1>

หรือกระบวนการเขียนชื่อไพพ์คืออะตอมหรือไม่

คำตอบ:


29

ขึ้นอยู่กับว่าแต่ละกระบวนการเขียนขึ้นมามากแค่ไหน (สมมติว่าระบบปฏิบัติการของคุณสอดคล้องกับ POSIX ในเรื่องนี้) จากwrite():

คำร้องขอการเขียนไปยังไพพ์หรือ FIFO จะได้รับการจัดการในลักษณะเดียวกับไฟล์ปกติโดยมีข้อยกเว้นดังต่อไปนี้:
[... ]

  • คำร้องขอการเขียนของ {PIPE_BUF} ไบต์หรือน้อยกว่าจะไม่ถูกสอดแทรกกับข้อมูลจากกระบวนการอื่น ๆ ที่ทำการเขียนบนไพพ์เดียวกัน การเขียนที่มีขนาดมากกว่า {PIPE_BUF} ไบต์อาจมี data interleaved ตามขอบเขตที่กำหนดไว้โดยการเขียนโดยกระบวนการอื่นไม่ว่าจะตั้งค่าสถานะ O_NONBLOCK ของสถานะไฟล์หรือไม่ก็ตาม

นอกจากนี้ในส่วนเหตุผลเกี่ยวกับท่อและ FIFO:

  • Atomic / non-atomic : การเขียนเป็น atomic ถ้าจำนวนทั้งหมดที่เขียนในการดำเนินการหนึ่งไม่ได้ถูกสอดแทรกด้วยข้อมูลจากกระบวนการอื่น ๆ สิ่งนี้มีประโยชน์เมื่อมีผู้เขียนหลายคนส่งข้อมูลไปยังผู้อ่านคนเดียว แอปพลิเคชันจำเป็นต้องทราบว่าคำขอการเขียนขนาดใหญ่สามารถคาดว่าจะดำเนินการแบบอะตอม ค่าสูงสุดนี้เรียกว่า {PIPE_BUF} ไดรฟ์ข้อมูลของ POSIX.1-2008 นี้ไม่ได้บอกว่าการร้องขอการเขียนมากกว่าไบต์ {PIPE_BUF} เป็นอะตอม แต่ต้องการให้การเขียนของ {PIPE_BUF} หรือน้อยกว่านั้นจะเป็นอะตอมมิก

ค่าหากPIPE_BUFถูกกำหนดโดยการใช้งานแต่ละครั้ง แต่อย่างน้อยที่สุดคือ 512 ไบต์ (ดูlimits.h) บน Linux มี 4096 ไบต์ (ดูpipe(7))


5
PIPE_BUF คือโดยวิธีการที่รับประกันว่าจะมีอย่างน้อย 512 โปรดทราบว่าคุณยังมีการรับประกันว่ากระบวนการของคุณจริงเขียนแต่ละบรรทัดไปในสายเดียวเขียน การเปิดใช้งานการบัฟเฟอร์บรรทัด ( setvbuf(stdout, NULL, _IOLBF,512)) จะทำเช่นนี้โดยไม่ต้องการให้คุณใช้ฟังก์ชั่นระดับต่ำ
Random832

นี่คือตารางPIPE_BUFค่าที่สังเกตได้ในระบบ Unix ทั่วไป: ar.to/notes/posix#pipe-buf
Arto Bendiken

ฉันไม่เข้าใจว่าซ็อกเก็ตสามารถทำมัลติเพล็กได้อย่างไร ... แต่ชื่อท่อไม่สามารถ ?? ทุกอย่างในยูนิกซ์เป็นไฟล์ใช่มั้ย lulz
Alexander Mills

@AlexanderMills: ฉันไม่เข้าใจความคิดเห็นของคุณ
Mat

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