2012-07-01 8 views
10

Miałem nadzieję, że użyję razem System.INotify i System.IO.MMap w celu oglądania modyfikacji plików, a następnie szybkiego wykonywania różnic dla wysyłania łatek przez sieć. Jednak w dokumentacji System.IO.MMap istnieje kilka ostrzeżeń dotyczących przejrzystości referencyjnym:Przejrzysta przezroczystość i mmap w Haskell

Dokumentacja stwierdza

Jest tylko bezpieczne mmap pliku, jeśli wiesz, że jesteś jedynym użytkownikiem. W przeciwnym razie przejrzystość referencyjna może być lub nie może być zagrożona. Niestety semantyka różni się znacznie pomiędzy systemami operacyjnymi.

Wartości, które mmap Powroty IO ByteString, z pewnością, gdy używam tej wartości z putStr Czekam inny wynik za każdym razem? Zakładam, że autor oznacza, że ​​wartość może się zmienić podczas operacji IO, takiej jak putStr i awarii?

START-EDYCJA: Przyjdź, pomyśl o tym, myślę, że odpowiedź na tę część pytania jest nieco oczywista ... Jeśli wartość zmieni się w dowolnym momencie po jej rozpakowaniu, będzie to problematyczne.

do 
    v <- mappedValue :: IO ByteString 
    putStr v 
    putStr v -- Expects the same value of v everywhere 

END-OF-Edit

Nie powinno to być możliwe, aby zdobyć jakąś blokadę na wyznaczonej regionu lub pliku?

Czy możliwe jest napisanie funkcji copy :: IO ByteString -> IO ByteString, która przechwyci migawkę pliku w jego bieżącym stanie w bezpieczny sposób?

+0

Brzmi jak to, co chcesz, można zrobić również z prostą parą rur. – leftaroundabout

+0

Jestem "oglądanie" plików w katalogu w nieco ogólny sposób. Jeśli którekolwiek narzędzie dotknie ich, klienci zostaną automatycznie zaktualizowani. –

+1

Czy naprawdę nie ma biblioteki mmap, która oferuje coś typu 'IO (Ptr Word8)' lub podobne? –

Odpowiedz

8

Myślę, że autor oznacza, że ​​wartość może się zmienić nawet w podniesionej funkcji, która może go wyświetlić jako zwykły ByteString (bez IO).

Zmapowany plik jest obszarem pamięci. Nie ma większego sensu kopiowanie jego treści tam i z powrotem, ze względu na wydajność (w przeciwnym razie można by zrobić zwykłe stare operacje we/wy strumieniowe). Więc ByteString, który otrzymujesz, jest na żywo.

Jeśli chcesz mieć migawkę, po prostu użyj operacji we/wy opartych na strumieniu. To właśnie czyta plik: tworzy migawkę pliku w pamięci! Domyślam się, że alternatywą byłoby użycie interfejsu ForeignPtr, który nie posiada referencyjnego ostrzeżenia o przezroczystości. Nie znam się na ForeignPtrs, więc nie mogę zagwarantować, że zadziała, ale wygląda obiecująco i chciałbym to zbadać.

Możesz również spróbować wywołać map id na swoim ByteString, ale nie można zagwarantować, że otrzymasz kopię odrębną od oryginału.

Obowiązkowe blokowanie plików, zwłaszcza w systemie Linux, to bałagan, którego lepiej unikać. Blokowanie plików doradczych jest w porządku, ale nikt go nie używa, więc w rzeczywistości nie istnieje.

+2

Domyślam się, że podświadomie I ' Spodziewam się trochę za dużo od mojego systemu operacyjnego. Zasadniczo chciałem traktować plik jak naprawdę szybką pamięć podręczną współużytkowanych pamięci między wieloma procesami, pozwalając OS'owi zadbać o spłukiwanie zmian na dysk do woli. Myśląc o tym ostrożniej, wydaje mi się, że wydaje się to mało prawdopodobne, chyba że wszystkie procesy jawnie wykorzystują wspólną mapę pamięci. –

+0

(Mam nadzieję, że uniknę opóźnienia związanego z dotykaniem dysku fizycznego ...) –