2010-09-28 8 views
12

Aby porównać diff przyległych rekordów z pliku, stworzyłem dwa FIFOs rozwidlone dzieci do dostarczenia ich końce pisać, a przechwycone wyjścieW Perl, w jaki sposób bezpiecznie utworzyć tymczasowy FIFO?

diff -ub $previous $current 

którym skalary zawierać FIFO Ścieżki aportem jak bash process substitution Prace.

To nie jest program, który musi być kuloodporny, ale gdyby tak było, w jaki sposób utworzyć tymczasowe FIFO, aby uniknąć race conditions i innych słabych punktów? Wyobraź sobie, że File::Temp ma kuzyna File::Temp::FIFO: jaka byłaby jego implementacja?

+0

z bash zastąpienia procesu, każdy proces w rurze jest zakończone przed 'diff' tj' diff <(LS $ first_directory) <(LS $ second_directory) 'każdy' ls 'jest kompletny w całości przed uruchomieniem' diff' na swoich wyjściach. Próbujesz zrobić ten sam rekord przez rekord ... – dawg

Odpowiedz

3

Zakładając, że wszystkie końce procesu są połączone z utworzonymi przez ciebie FIFO, czy nie możesz ich usunąć z systemu plików? Otwarte uchwyty plików zapobiegną usunięciu FIFO, ale nie można do niego dołączyć żadnych nowych uchwytów, a gdy istniejące uchwyty plików zostaną zamknięte, sama FIFO zniknie.

+0

W systemie Unix powinno być dobrze - Nie mogę odpowiedzieć dla systemu Windows. Drugi problem, jaki widzę, polega na tym, że 'mkfifo' obserwuje niekompletne dowiązania symboliczne? W systemie MacOS X zarówno polecenie powłoki, jak i wywołanie systemowe nie działają z EEXISTS. Warto również wybrać losowe nazwy dla FIFO. –

+0

Moje pytanie koncentruje się na tworzeniu FIFO, ale ta odpowiedź wydaje się zakładać je jako dane. czego mi brakuje? –

+0

Cóż, wspomniałeś w swoim pytaniu, że "stworzyłem dwa FIFO"? Tak czy inaczej, możesz je utworzyć za pomocą komend systemu 'mkfifo' lub' mknod'. – zigdon

6

Co zrobić, aby utworzyć katalog tymczasowy (a la mkdtemp()), aby uniknąć warunków wyścigu, a następnie umieścić tam swoje FIFO?

Na przykład:

use File::Temp qw(tempdir); 
use File::Spec::Functions qw(catfile); 
use POSIX qw(mkfifo); 

my $dir = tempdir(CLEANUP=>1); 
my $fifo0 = catfile($dir, "fifo0"); 
mkfifo($fifo0, 0700) or die "mkfifo($fifo0) failed: $!"; 
my $fifo1 = catfile($dir, "fifo1"); 
mkfifo($fifo1, 0700) or die "mkfifo($fifo1) failed: $!"; 

print "FIFO #0: $fifo0\n"; 
print "FIFO #1: $fifo1\n"; 
+0

Dlaczego dwa katalogi? Potrzebują co najmniej dwa razy więcej sprzątania. Jeden katalog jest wystarczający. –

+0

Hmmm .. Byłem zbyt sprytny dla własnego dobra. Masz rację, potrzebny jest tylko jeden katalog tymczasowy. –

+1

Nie zapomnij sprawdzić, czy 'tempdir' się powiódł. –

Powiązane problemy