เนื่องจากโปรแกรมของคุณอาจกำลังรอ I / O หรือถูกระงับ SIGPIPE ขัดจังหวะโปรแกรมของคุณแบบอะซิงโครนัสยุติการเรียกระบบและสามารถจัดการได้ทันที
อัปเดต
A | B | C
พิจารณาท่อ
เพื่อความชัดเจนเราจะถือว่า B คือลูปสำเนามาตรฐาน:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
ถูกบล็อกในการรอสายอ่าน (2)สำหรับข้อมูลA
เมื่อC
สิ้นสุด หากคุณรอรหัสส่งคืนจากการเขียน (2) B จะเห็นเมื่อใด แน่นอนว่าคำตอบคือไม่ใช่จนกว่า A จะเขียนข้อมูลเพิ่มเติม (ซึ่งอาจต้องรอนาน - จะเกิดอะไรขึ้นถ้า A ถูกบล็อกโดยสิ่งอื่น?) สังเกตว่าสิ่งนี้ยังช่วยให้เรามีโปรแกรมที่ง่ายและสะอาดขึ้น หากคุณขึ้นอยู่กับรหัสข้อผิดพลาดจากการเขียนคุณจะต้องมีสิ่งต่อไปนี้:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
การปรับปรุงอื่น ๆ
อ๊ะคุณสับสนเกี่ยวกับพฤติกรรมของการเขียน คุณจะเห็นเมื่อตัวอธิบายไฟล์ที่มีการเขียนที่รอดำเนินการถูกปิด SIGPIPE จะเกิดขึ้นทันที แม้ว่าการเขียนจะส่งกลับ -1 ในที่สุดจุดรวมของสัญญาณคือการแจ้งให้คุณทราบแบบอะซิงโครนัสว่าไม่สามารถเขียนได้อีกต่อไป นี่เป็นส่วนหนึ่งของสิ่งที่ทำให้โครงสร้าง Co-routine ที่สวยงามทั้งหมดของท่อทำงานใน UNIX
ตอนนี้ฉันสามารถชี้ให้คุณเห็นการอภิปรายทั้งหมดในหนังสือการเขียนโปรแกรมระบบ UNIX หลายเล่ม แต่มีคำตอบที่ดีกว่า: คุณสามารถยืนยันได้ด้วยตัวเอง เขียนง่ายB
โปรแกรม [1] - คุณได้มีความกล้าที่มีอยู่แล้วสิ่งที่คุณต้องเป็นmain
และบางส่วนรวมถึง - SIGPIPE
และเพิ่มตัวจัดการสัญญาณ เรียกใช้ไปป์ไลน์เช่น
cat | B | more
และในหน้าต่างเทอร์มินัลอื่นแนบดีบักเกอร์กับ B และวางเบรกพอยต์ไว้ในตัวจัดการสัญญาณ B
ตอนนี้ฆ่าได้มากขึ้นและ B ควรทำลายตัวจัดการสัญญาณของคุณ ตรวจสอบสแต็ก คุณจะพบว่าการอ่านยังคงค้างอยู่ ให้สัญญาณจัดการดำเนินการและการกลับมาและดูที่ผลที่ส่งกลับโดยเขียน - ซึ่งจะแล้วจะ -1
[1] โดยปกติคุณจะเขียนโปรแกรม B ของคุณในภาษา C :-)
write
.