我需要處理大量資料流。流大于 RAM 中的容量。
流需要按順序對其應用多個轉換。相互通信的異步執行任務的管道可以很好地作業,就像下面的 shell 管道:
producer | transform1 | transform1 | transform2 | consumer
其中一些轉換最好通過命令列實用程式來實作,這些實用程式接受來自 STDIN 的輸入并將其輸出生成到 STDOUT。
但是其中一些轉換用 Perl 撰寫起來很簡單。我想避免必須管理許多小腳本,所以我希望它們由啟動管道的程式中的 Perl 子程式處理。這些 subs 需要在子行程中運行,從 STDIN 讀取并寫入 STDOUT,就像此管道中的其他任務一樣。這意味著我不能只使用system.
如何在 Perl 中實作這個管道?
uj5u.com熱心網友回復:
將myfunc1、myfunc2和myfunc3接受輸入作為子例程的引數,并將輸出作為子程式的回傳值回傳。也就是改變
sub myfunc1 {
while (<STDIN>) {
do something
print STDOUT $_;
}
}
類似于
sub myfunc1 {
return map {
do something;
$_
} @_;
}
然后你可以鏈接你的函式,如:
print STDOUT myfunc3(myfunc2(myfunc1(<STDIN>)));
uj5u.com熱心網友回復:
該IPC::Run軟體包將為您執行此操作。
#! /usr/bin/perl
use IPC::Run qw(run);
my @cat = qw(cat);
my @wc = qw(wc -l);
run @cat, '|', \@wc;
uj5u.com熱心網友回復:
# This is the function to do the work
sub pipefunc {
my $func = pop;
my $pid = open(my $kid_to_read, "-|");
defined($pid) || die "can't fork: $!";
if ($pid) {
open STDIN, "<&", $kid_to_read or die;
&$func();
} else { # child
close $kid_to_read;
if($_[1]) {
# More than one function remaining: Recurse
pipefunc(@_);
} else {
# Only one function remaining: Run it
$func = pop;
&$func();
}
exit 0;
}
}
sub func1 {
# Run some UNIX filter, that reads STDIN and prints to STDOUT
while(<STDIN>) {
print "foo $_";
}
}
sub func2 {
# Run some UNIX filter, that reads STDIN and prints to STDOUT
while (<STDIN>) {
print "bar $_";
}
}
sub func3 {
# Run some UNIX filter, that reads STDIN and prints to STDOUT
exec q{perl -pe 's/o/e/g; s/a/i/g;'};
}
sub func4 {
# Run some UNIX filter, that reads STDIN and prints to STDOUT
exec q{perl -pe 's/^/A/g; s/$/B/g;'};
}
# This is how you use it.
# func4 | func2 | func1 | func3 | func2 | func4
pipefunc(\&func4,\&func2,\&func1,\&func3,\&func2,\&func4);
嘗試:
seq 10 | perl pipefunc.pl
就像 shell 中的管道一樣,這將在大于系統虛擬記憶體的輸入上正常作業。就像 shell 中的管道一樣,它會為每個函式運行一個行程。
使用system它很容易將 perl 函式與 shell 命令混合使用,因此通過將 shell 命令包裝在其中sub myfunc { system "shell command"; }可以獲得以下效果:perlfunc | shell command | perlfunc | perlfunc | shell command。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/450445.html
上一篇:如何在Perl中為Selenium::Chrome設定ChromeOptions(或goog:ChromeOptions)
下一篇:Perl:子程式不均勻/例外行為
