จากการอ่าน man page บนread()
และการwrite()
โทรปรากฏว่าการโทรเหล่านี้ถูกขัดจังหวะด้วยสัญญาณโดยไม่คำนึงว่าพวกเขาจะต้องปิดกั้นหรือไม่
โดยเฉพาะสมมติว่า
- กระบวนการสร้างตัวจัดการสำหรับสัญญาณบางอย่าง
- อุปกรณ์ถูกเปิด (พูดเทอร์มินัล) โดยที่
O_NONBLOCK
ไม่ได้ตั้งค่า (เช่นทำงานในโหมดบล็อก) - กระบวนการนี้ทำให้การ
read()
เรียกระบบอ่านจากอุปกรณ์และผลลัพธ์จะดำเนินการพา ธ ควบคุมเคอร์เนลในเคอร์เนลพื้นที่ - ในขณะที่กระบวนการดำเนินการอยู่
read()
ใน kernel-space สัญญาณที่ติดตั้งตัวจัดการไว้ก่อนหน้านี้จะถูกส่งไปยังกระบวนการนั้นและตัวจัดการสัญญาณถูกเรียกใช้
การอ่าน man man และส่วนที่เหมาะสมในSUSv3 'System Interfaces volume (XSH)' , หนึ่งพบว่า:
ผม. หาก a read()
ถูกขัดจังหวะโดยสัญญาณก่อนที่จะอ่านข้อมูลใด ๆ (นั่นคือต้องปิดกั้นเพราะไม่มีข้อมูล) จะส่งกลับ -1 ด้วยการerrno
ตั้งค่าเป็น [EINTR]
ii หาก a read()
ถูกขัดจังหวะโดยสัญญาณหลังจากอ่านข้อมูลเรียบร้อยแล้ว (เช่นเป็นไปได้ที่จะเริ่มให้บริการตามคำขอทันที) มันจะส่งคืนจำนวนไบต์ที่อ่าน
คำถาม A):
ฉันถูกต้องหรือไม่ที่จะสมมติว่าในกรณีใด ๆ (บล็อก / ไม่มีบล็อก) การส่งและการจัดการสัญญาณไม่โปร่งใสอย่างสิ้นเชิงกับread()
?
กรณีที่ ดูเหมือนจะเข้าใจได้เนื่องจากการบล็อกread()
ปกติจะวางกระบวนการในTASK_INTERRUPTIBLE
สถานะเพื่อให้เมื่อมีการส่งสัญญาณเคอร์เนลจะวางกระบวนการให้อยู่ในTASK_RUNNING
สถานะ
อย่างไรก็ตามเมื่อread()
ไม่จำเป็นต้องปิดกั้น (กรณีที่ ii) และกำลังประมวลผลการร้องขอในเคอร์เนลพื้นที่ฉันจะคิดว่าการมาถึงของสัญญาณและการจัดการของมันจะมีความโปร่งใสมากเช่นการมาถึงและการจัดการ HW ที่เหมาะสม ขัดจังหวะจะเป็น โดยเฉพาะอย่างยิ่งฉันจะสันนิษฐานว่าเมื่อส่งสัญญาณกระบวนการจะถูกวางไว้ชั่วคราวในโหมดผู้ใช้เพื่อดำเนินการจัดการสัญญาณของมันซึ่งมันจะกลับมาในที่สุดก็จะเสร็จสิ้นการประมวลผลขัดจังหวะread()
(ในเคอร์เนลพื้นที่) เพื่อให้read()
ทำงาน แน่นอนว่าจะเสร็จสิ้นหลังจากที่กระบวนการส่งคืนกลับไปยังจุดหลังจากการเรียกไปที่read()
(ในพื้นที่ผู้ใช้) โดยไบต์ทั้งหมดที่มีอยู่จะอ่านเป็นผลลัพธ์
แต่ครั้งที่สอง ดูเหมือนว่าบ่งบอกว่าข้อมูลread()
ถูกขัดจังหวะเนื่องจากข้อมูลสามารถใช้งานได้ทันที แต่จะส่งคืนข้อมูลเพียงบางส่วนเท่านั้น (แทนที่จะเป็นทั้งหมด)
สิ่งนี้ทำให้ฉันถึงคำถามที่สอง (และครั้งสุดท้าย):
คำถามข):
หากการสันนิษฐานของฉันภายใต้ A) ถูกต้องทำไมการread()
ถูกขัดจังหวะแม้ว่ามันจะไม่จำเป็นต้องปิดกั้นเพราะมีข้อมูลที่สามารถตอบสนองคำขอได้ทันที? กล่าวอีกนัยหนึ่งทำไมread()
ไม่ดำเนินการต่อหลังจากเรียกใช้งานตัวจัดการสัญญาณในที่สุดก็ส่งผลให้ข้อมูลที่มีอยู่ทั้งหมด (ซึ่งมีอยู่หลังจากทั้งหมด) ถูกส่งกลับ?