當談到Perl如何處理POSIX信號時,我遇到了一些問題。也就是說,Perl似乎忽略了這些信號,除非在sleep()
的調用中收到它們。Perl 5.10 - POSIX信號被忽略,除非在sleep()調用期間收到?
例如,下面的代碼工作正常:
#/usr/bin/perl
$SIG{PIPE} = sub { print STDERR "WARNING: Received SIGPIPE"; exit(1); };
while (1) { print "Waiting on signal...\n"; sleep(10); }
當使用其他腳本從Oracle數據庫讀取上面的SIGPIPE處理程序,子程序似乎永遠不會被調用。
#/usr/bin/perl
use DBI;
$SIG{PIPE} = sub { print STDERR "WARNING: Received SIGPIPE"; exit(1); };
my $db = "redacted";
my $user = "redacted";
my $pass = "redacted";
my $table = "redacted";
my $ora = DBI->connect("dbi:Oracle:" . $db, $user, $pass);
my $sql = "SELECT * FROM " . $table;
my $query = $ora->prepare($sql);
$query->execute();
while (my @row = $query->fetchrow_array()) {
print(join('|', @row) . "\n");
}
if ($DBI::err) { print STDERR "ERROR: Unload terminated due to error"; }
我發送SIGPIPE信號,以同樣的方式(kill -sPIPE pid
)這兩個腳本,但只有第一個腳本對其作出響應。第二個腳本只是繼續。沒有消息,沒有退出,什麼都沒有。
我該如何糾正這種情況?
無法重現。 Oracle驅動程序是否可能也試圖使用'$ SIG {PIPE}'?在執行調用之前和之後檢查'$ SIG {PIPE}'的值。 – mob
我在執行調用之前/之後得到相同的代碼散列。爲了確保設置值,我還在設置處理程序之前打印了值(它已按預期更新)。爲了使問題複雜化,在處理循環之前添加一個「sleep(30)」可以使其捕獲信號,但只能在睡眠期間進行。 –
讀取不生成SIGPIPE;當您嘗試寫入沒有接收器進程的管道或套接字時,您會收到SIGPIPE。 –