Tôi đang thực hiện truy cập tập tin rất nhanh chóng trong ruby (2.0.0 p39474), và tiếp tục nhận được ngoại lệ Too many open files
của Ruby xử lý tập tin quản lý (quá nhiều tập tin mở)
Sau khi nhìn this thread, here, và các nguồn khác nhau , Tôi biết rõ về các giới hạn của hệ điều hành (được đặt thành 1024
trên hệ thống của tôi).
Phần mã của tôi mà thực hiện tập tin này truy cập được mutexed, và có dạng:
File.open(filename, 'w'){|f| Marshal.dump(value, f) }
nơi filename
là tùy thuộc vào sự thay đổi nhanh chóng, tùy thuộc vào các chủ đề kêu gọi phần này. Đó là sự hiểu biết của tôi rằng hình thức này từ bỏ xử lý tập tin của nó sau khi khối.
Tôi có thể xác minh số lượng File
đối tượng đang mở sử dụng ObjectSpace.each_object(File)
. Điều này báo cáo rằng có đến 100 cư dân trong bộ nhớ, nhưng chỉ có một là bao giờ mở, như mong đợi.
Hơn nữa, bản thân ngoại lệ được ném vào thời điểm chỉ có 10-40 File
đối tượng được báo cáo bởi ObjectSpace
. Hơn nữa, việc thu thập rác theo cách thủ công không cải thiện bất kỳ số đếm nào trong số này, cũng như làm chậm tập lệnh của tôi bằng cách chèn các cuộc gọi sleep
.
Câu hỏi của tôi là, do đó:
-
Am tôi về cơ bản hiểu lầm về bản chất của giới hạn hệ điều hành --- nó bao trùm toàn bộ cuộc đời của một quá trình?-
Nếu có, làm cách nào để máy chủ web tránh bị trục trặc sau khi truy cập trênulimit -n
tệp? -
Có phải ruby giữ lại các tệp xử lý bên ngoài hệ thống đối tượng hay hạt nhân chỉ đơn giản là rất chậm khi tính truy cập 'đồng thời'?
-
Sửa 20.130.417: strace
chỉ ra rằng ruby không ghi tất cả dữ liệu của mình cho các tập tin, trở về và phát hành các mutex trước khi làm như vậy. Như vậy, các tập tin xử lý stack lên cho đến khi giới hạn hệ điều hành.
Để khắc phục điều này, tôi đã sử dụng syswrite
/sysread
, chế độ đồng bộ và được gọi là flush
trước close
. Không có phương pháp nào trong số này hoạt động.
Câu hỏi của tôi do đó được sửa đổi thành: Tại sao ruby không đóng các xử lý tệp của nó và làm thế nào tôi có thể buộc nó làm như vậy?
'strace' chỉ ra rằng ruby mở tệp, sau đó trả về từ hàm, giải phóng mutex trước khi dữ liệu được ghi. Trong một số trường hợp, nó thậm chí không tuôn ra, và kết thúc bằng văn bản vào đĩa khi đóng tài nguyên sau khi ngoại lệ (tức là trong khi tắt máy). –