Từ việc đọc các trang man trên read()
và write()
gọi, có vẻ như các cuộc gọi này bị gián đoạn bởi các tín hiệu bất kể chúng có phải chặn hay không.
Đặc biệt, giả sử
- một quá trình thiết lập một xử lý cho một số tín hiệu.
- một thiết bị được mở (giả sử, một thiết bị đầu cuối)
O_NONBLOCK
không được đặt (tức là hoạt động ở chế độ chặn) - quá trình sau đó thực hiện một
read()
cuộc gọi hệ thống để đọc từ thiết bị và kết quả là thực thi một đường dẫn điều khiển kernel trong không gian kernel. - trong khi điều kiện tiên quyết đang thực hiện
read()
trong không gian kernel, tín hiệu mà trình xử lý được cài đặt trước đó được gửi đến quá trình đó và trình xử lý tín hiệu của nó được gọi.
Đọc các trang hướng dẫn và các phần thích hợp trong SUSv3 volume Âm lượng giao diện hệ thống (XSH) ' , người ta thấy rằng:
tôi. Nếu a read()
bị gián đoạn bởi tín hiệu trước khi nó đọc bất kỳ dữ liệu nào (nghĩa là nó phải chặn vì không có dữ liệu nào), nó sẽ trả về -1 khi errno
được đặt thành [EINTR].
ii. Nếu a read()
bị gián đoạn bởi tín hiệu sau khi nó đã đọc thành công một số dữ liệu (nghĩa là có thể bắt đầu phục vụ yêu cầu ngay lập tức), nó sẽ trả về số byte đã đọc.
Câu hỏi A):
Tôi có đúng không khi cho rằng trong cả hai trường hợp (khối / không chặn) việc phân phối và xử lý tín hiệu không hoàn toàn trong suốt đối với read()
?
Trường hợp i. có vẻ dễ hiểu vì việc chặn read()
thông thường sẽ đặt tiến trình ở TASK_INTERRUPTIBLE
trạng thái để khi tín hiệu được phát, hạt nhân đặt tiến trình vào TASK_RUNNING
trạng thái.
Tuy nhiên, khi read()
không cần chặn (trường hợp ii.) Và đang xử lý yêu cầu trong không gian hạt nhân, tôi đã nghĩ rằng sự xuất hiện của tín hiệu và việc xử lý nó sẽ minh bạch giống như việc đến và xử lý đúng cách một CTNH gián đoạn sẽ là. Cụ thể, tôi đã giả định rằng khi phát tín hiệu, quá trình sẽ tạm thời được đưa vào chế độ người dùng để thực thi trình xử lý tín hiệu của nó, từ đó cuối cùng nó sẽ quay trở lại để xử lý gián đoạn read()
(trong không gian kernel) để read()
chạy nó Tất nhiên để hoàn thành sau đó quá trình quay trở lại điểm ngay sau khi gọi đến read()
(trong không gian người dùng), với tất cả các byte có sẵn được đọc như là kết quả.
Nhưng ii. dường như ngụ ý rằng read()
nó bị gián đoạn, vì dữ liệu có sẵn ngay lập tức, nhưng nó chỉ trả về một số dữ liệu (thay vì tất cả).
Điều này đưa tôi đến câu hỏi thứ hai (và cuối cùng):
Câu hỏi B):
Nếu giả định của tôi theo A) là chính xác, tại sao việc này read()
bị gián đoạn, mặc dù không cần phải chặn vì có sẵn dữ liệu để đáp ứng yêu cầu ngay lập tức? Nói cách khác, tại sao việc read()
không được nối lại sau khi thực hiện trình xử lý tín hiệu, cuối cùng dẫn đến tất cả các dữ liệu có sẵn (có sẵn sau khi tất cả) được trả về?