ja wykonujące bardzo szybki dostęp do plików w Ruby (2.0.0 p39474), i wciąż otrzymuję wyjątek Too many open files
Ruby zarządzanie uchwyt pliku (zbyt wiele otwartych plików)
Spojrzeliśmy na this thread, here i różne inne źródła , Dobrze znam ograniczenia systemu operacyjnego (ustawione na 1024
w moim systemie).
Część mojego kodu, który wykonuje ten plik dostępu mutexed i przybiera postać:
File.open(filename, 'w'){|f| Marshal.dump(value, f) }
gdzie filename
podlega szybkim zmianom, w zależności od wywołującego wątku sekcję. Rozumiem, że ta forma rezygnuje z obsługi pliku po bloku.
Mogę zweryfikować liczbę obiektów File
, które są otwarte przy użyciu ObjectSpace.each_object(File)
. Oznacza to, że w pamięci jest maksymalnie 100 rezydentów, ale tylko jeden jest otwarty, zgodnie z oczekiwaniami.
Ponadto, sam wyjątek jest zgłaszany w czasie, gdy obiekty o numerach 10-40 File
są zgłaszane przez ObjectSpace
. Ponadto, ręczne zbieranie nieużytków nie poprawi żadnego z tych obliczeń, podobnie jak spowolnienie mojego skryptu poprzez wstawienie wywołań sleep
.
Moje pytanie brzmi zatem:
-
Am I zasadniczo niezrozumienia charakteru granicy OS --- nie obejmuje cały okres procesu?-
Jeśli tak, to w jaki sposób serwery internetowe unikają awarii po uzyskaniu dostępu do plików ponadulimit -n
? -
Czy ruby zachowuje swoje uchwyty plików poza systemem obiektowym, czy też jądro po prostu bardzo wolno liczy się z "współbieżnym" dostępem?
-
Edit 20130417: strace
wskazuje, że Ruby nie zapisuje wszystkie dane do pliku, wracając i zwalniając mutex przed tym zakresie. W związku z tym plik obsługuje stos aż do limitu systemu operacyjnego.
Próbując naprawić to, użyłem syswrite
/sysread
, tryb synchroniczny, a nazywa flush
przed close
. Żadna z tych metod nie zadziałała.
Moje pytanie zostało zmienione na: Dlaczego ruby nie może zamknąć swoich uchwytów plików i jak mogę to zmusić?
'strace' wskazuje, że rubin otwiera plik, a następnie wraca z funkcji, zwalniając muteks przed zapisaniem danych. W niektórych przypadkach nawet się nie wypala i kończy na zapisie na dysku podczas zamykania zasobów po wystąpieniu wyjątku (np. Podczas zamykania). –