[Mặc dù tôi đang làm việc trong perl nhưng tôi tin rằng câu hỏi này liên quan đến Linux System V IPC
API và giới hạn thay vì bất kỳ thứ gì cụ thể cho perl.]
Tôi có hai máy Centos, mỗi máy tại CentOS Linux phát hành 7.9.2009 (Core).
Tôi có một chương trình chia rẽ một đứa trẻ và sau đó sử dụng các thông báo IPC của Hệ thống V để giao tiếp với đứa trẻ, đứa trẻ chuẩn bị câu trả lời và gửi chúng cho phụ huynh.
Trên một máy, chúng tôi thấy hành vi dự kiến. Đứa trẻ tạo ra hàng loạt tin nhắn, cha mẹ tiêu thụ chúng. Đôi khi, đứa trẻ làm việc nhanh hơn cha mẹ một chút và do đó có thể lấp đầy hàng đợi, sau đó đứa trẻ đợi cho đến khi cha mẹ tiêu thụ một số tin nhắn và tiếp tục.
Chúng tôi có thể kiểm tra kích thước hàng đợi bằng ipcs -q và thấy rằng đôi khi đạt đến giới hạn mặc định là 10 thư trên mỗi hàng đợi, phần tử con tạm dừng và sau đó chúng tôi thấy hàng đợi trống như mong đợi.
Chúng tôi tin rằng giới hạn hàng đợi được chỉ định trong các tệp trong /proc/sys/fs/mqueue/ và ví dụ msg_max được coi là 10 dự kiến.Các giá trị này giống hệt nhau trên cả hai máy.
Chúng tôi cũng có thể xem ulimits của người dùng liên quan đến hàng đợi bằng cách sử dụng ulimit -q và thấy giá trị vượt quá 800.000 byte trên cả hai máy.
Điều khó hiểu là trên máy thứ hai của chúng tôi, chúng tôi thấy đứa trẻ viết ba tin nhắn vào hàng đợi và cố gắng viết tin nhắn thứ tư và đợi - chúng tôi cố tình không đặt thời gian chờ.
Như thể người viết tin rằng hàng đợi đã đầy, mặc dù ipcs -q chỉ hiển thị 3 mục trong hàng đợi. Tại thời điểm này, cha mẹ vẫn chưa cố gắng đọc tin nhắn.
------ Hàng đợi tin nhắn --------
chủ sở hữu msqid chính cho phép các tin nhắn byte đã sử dụng
0x0000002a 1474560 dave 600 15020 3
Câu hỏi: ngoài việc hàng đợi đầy, điều gì sẽ khiến msgsnd() tạm dừng?
Việc tạm dừng dường như tiếp tục vô thời hạn, đứa trẻ tiếp tục khi cha mẹ
trở nên hoạt động và đọc một số tin nhắn.
Chúng tôi có nhiều máy chạy mã này mà không gặp sự cố. Nó không thành công trên ba máy mới.
Có lẽ có một số tính năng dành riêng cho môi trường tương tác với mã của chúng tôi?
Mã perl sử dụng một thư viện nhỏ phía trên các lệnh gọi hệ thống (chi tiết được nêu rõ)
$mQueue = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR);
msgsnd( $mQueue, pack("l! a*", length($msg), $msg);