2011-06-27 8 views
10

Czy istnieje sposób tworzenia nie blokowania/asynchronicznego nazwanego potoku lub czegoś podobnego w powłoce? Aby programy mogły umieszczać w nim linie, te linie pozostałyby w pamięci RAM, a kiedy jakiś program mógłby odczytać kilka linii z rury, pozostawiając to, czego nie przeczytał w fifo? Jest również bardzo prawdopodobne, że programy mogą jednocześnie pisać i czytać do tej liczby. Na początku, choć może to można zrobić za pomocą plików, ale po przeszukiwaniu sieci na chwilę wydaje się, że nic dobrego nie może pochodzić z faktu, że plik jest czytany i zapisywany w tym samym czasie. Nazwane potoki będą prawie działać, tylko są dwa problemy: najpierw blokują odczyty/zapisy, jeśli nie ma nikogo na drugim końcu, po drugie, nawet jeśli zezwolę na pisanie do zablokowania i ustawię dwa procesy, aby pisać do potoku, gdy nikt nie czyta, próbując napisać jedną linię z każdym procesem, a następnie spróbuj head -n 1 <fifo> Dostaję tylko jedną linię, gdy potrzebuję, ale oba procesy zapisu kończą się, a druga linia jest tracona. Jakieś sugestie?Nonblocking/asynchroniczne fifo/named pipe w powłoce/systemie plików?

Edycja: może jakiś program pośredni mógłby zostać użyty, by pomóc w tym, zachowując się jak mediator między pisarzami i czytelnikami?

+2

Można zrobić coś takiego 'mkfs/dev/ram1 1048576' (lub większej liczby jeśli chcesz) i zamontować'/dev/ram1' nigdzie wtedy. Jest to prawdopodobnie tak bliskie "niezablokowania", jak to tylko możliwe. Oczywiście, domyślnie nie będzie to wcale blokowanie, tylko bardzo szybko (ale domyślna rura też nie będzie domyślnie). Operacja Nonblocking jest czymś, co program musi ustawić na deskryptorze pliku. – Damon

+0

Chyba o tej opcji, utwórz plik w tmpfs lub podobnym, ale potem znowu problem pisania i czytania w tym samym czasie trwa. Bardziej przypomina pisanie i pisanie od czasu jego pliku. Jeden program zapisuje na końcu pliku, inne przeczytał kilka informacji od początku i teraz musi usunąć pierwsze wiersze, więc pisząc na końcu i usuwając z przodu w tym samym czasie, nie mogłem znaleźć rozwiązania tego, bym użył to. – morphles

+1

To trudne (jeśli nie niemożliwe) zrobić coś takiego bez pisania programu. Coś, co może działać najskuteczniej: zmiana nazwy jest atomowa, więc każdy z producentów może zapisać każde oddzielne zadanie do indywidualnego pliku tymczasowego, zamknąć plik i zmienić jego nazwę zgodnie z pewnym "dobrze znanym" wzorcem. Każdy konsument mógł zmienić nazwę następnego pliku na coś losowego (aby inny konsument go nie odebrał), przeczytać zawartość i usunąć plik. Chociaż działałoby to tylko na poziomie zadania (bez względu na to, jak producenci piszą jako jedna jednostka), a nie na poziomie linii. – Damon

Odpowiedz

5

Możesz użyć specjalnego programu do tego celu - bufora. Bufor został zaprojektowany tak, aby starać się utrzymać stronę pisarza ciągle zajętą, aby mógł przesyłać strumieniowo podczas zapisu na napędy taśmowe, ale można go używać do innych celów. Bufor wewnętrzny to para procesów komunikujących się za pośrednictwem dużej okrągłej kolejki przechowywanej w pamięci współdzielonej, dzięki czemu procesy będą działać asynchronicznie. Twój proces czytania zostanie zablokowany w przypadku, gdy kolejka jest pełna i proces pisarza - na wypadek, gdyby kolejka była pusta. Przykład:

bzcat archive.bz2 | bufor -m 16000000 -b 100000 | processing_script | bzip2> archive_processed.bz2

http://linux.die.net/man/1/buffer

+0

Dziękuję za wskazanie programu, którego nie znałem, wydaje się interesujący i może być przydatny w niektórych przypadkach. Chociaż nie jest to dokładnie to, czego chciałem i nie będę w stanie zrobić tego, co chcę, zdecydowałem, że najprawdopodobniej zaimplementuję własny program/demona w takich przypadkach jak moja. – morphles

+0

Innym rozwiązaniem byłoby użycie demona kolejki, coś w rodzaju ekwipunku. Twoje "linie" mogą trwać w memcache jako zadania. –

Powiązane problemy