持续更新中…
NAME
命名
perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocesses, sockets, and semaphores)
perlipc-perl进程间通信(signals, fifos, pipes, safe subprocesses, sockets, and semaphores)
DESCRIPTION
描述
The basic IPC facilities of Perl are built out of the good old Unix signals, named pipes, pipe opens, the Berkeley socket routines, and SysV IPC calls. Each is used in slightly different situations.
Perl的基本IPC工具是建立在良好的经典Unix信号,命名管道,pipe opens, the Berkeley socket routines, and SysV IPC 的调用基础上。每一种都在略有不同的地方使用。
Signals
信号
Perl uses a simple signal handling model: the %SIG hash contains names or references of user-installed signal handlers.
Perl使用了一个简单的信号处理模型:SIG哈希包含了用户建立的信号处理器的名字或者引用。
These handlers will be called with an argument which is the name of the signal that triggered it.
这些处理器会通过信号的名字来调用,从而触发信号。
A signal may be generated intentionally from a particular keyboard sequence like control-C or control-Z, sent to you from another process, or triggered automatically by the kernel when special events transpire, like a child process exiting, your own process running out of stack space, or hitting a process file-size limit.
一个信号可能会通过有意的组合键盘操作来生成,比如ctrl + c或者ctrl + z,这个信号会从一个进程中发送给你,或者上述操作会导致一些特殊的事情发生,从而使得内核会自动触发信号,特殊的事情比如一个子进程的退出,你自己的进程运行中栈空间内存溢出,或者超过了一个进程文件的大小限制。
For example, to trap an interrupt signal, set up a handler like this:
比如说,像下面这样建立一个处理器来获取一个中断信号:
our $shucks;
sub catch_zap {
my $signame = shift;
$shucks++;
die "Somebody sent me a SIG$signame";
}
$SIG{INT} = __PACKAGE__ . "::catch_zap";
$SIG{INT} = \&catch_zap; # best strategy
Prior to Perl 5.8.0 it was necessary to do as little as you possibly could in your handler; notice how all we do is set a global variable and then raise an exception.
在perl5.8.0之前,在你的处理器中少做事情是有必要的;注意到,我们只是设置了一个全局变量,然后引发一个异常。
That’s because on most systems, libraries are not re-entrant; particularly, memory allocation and I/O routines are not.
那是因为在大多数系统中,库是不能被重新导入的;特殊的是内存分配和I/O活动,它俩会重新导入库(??)。
That meant that doing nearly anything in your handler could in theory trigger a memory fault and subsequent core dump - see Deferred Signals (Safe Signals) below.
也就是说,在你的处理器中几乎做任何事都会导致内存错误,和后续的core dump - 查看下面的 延迟信号(安全信号)。
The names of the signals are the ones listed out by kill -l on your system, or you can retrieve them using the CPAN module IPC::Signal.
在你系统上的这些信号名字是通过 kill -l命令展示出来的,你可以通过CPAN模块IPC::Signal 重新获取它们
You may also choose to assign the strings “IGNORE” or “DEFAULT” as the handler, in which case Perl will try to discard the signal or do the default thing.
你可能也会选择分配一个字符串“IGNORE”或者 “DEFAULT”作为一个处理器,在这种情况下,perl将会尝试放弃这个信号或者做默认操作。
On most Unix platforms, the CHLD (sometimes also known as CLD ) signal has special behavior with respect to a value of “IGNORE” . Setting SIGCHLDto"IGNORE"onsuchaplatformhastheeffectofnotcreatingzombieprocesseswhentheparentprocessfailstowait()onitschildprocesses(i.e.,childprocessesareautomaticallyreaped).Callingwait()with SIG{CHLD} set to “IGNORE” usually returns -1 on such platforms.
在大多数Unix平台上,CHLD(有时候也被成为CLD)信号对于IGNORE情况的时候会有特殊的表现。在一个平台上设置$SIG{CHLD} 为 “IGNORE”,该平台在父进程等待子进程失败的时候不会创建僵尸进程(比如,子进程会自动被回收)。在这样的平台上,调用wait()方法经常会返回-1。
Some signals can be neither trapped nor ignored, such as the KILL and STOP (but not the TSTP) signals. Note that ignoring signals makes them disappear. If you only want them blocked temporarily without them getting lost you’ll have to use POSIX’ sigprocmask.
有些信号既不会被捕获也不可以忽略,比如KILL和STOP(不是TSTP)信号。我们要注意到,忽略信号会让它们消失,所以,如果你不想让它们消失,只是想让他们暂时的阻塞,那么你必须使用POSIX sigprocmask(根据参数对信号执行阻塞)。
Sending a signal to a negative process ID means that you send the signal to the entire Unix process group. This code sends a hang-up signal to all processes in the current process group, and also sets $SIG{HUP} to “IGNORE” so it doesn’t kill itself:
发送一个信号给一个负数进程ID,意味着你发送这个信号给整个UNIX进程组。下面的代码发送了一个挂起信号给当前进程组的所有进程,而且设置了$SIG{HUP} 为 “IGNORE” ,所以它不会杀死自己。
# block scope for local
{
local $SIG{HUP} = "IGNORE";
kill HUP => -$$;
# snazzy writing of: kill("HUP", -$$)
}
Another interesting signal to send is signal number zero. This doesn’t actually affect a child process, but instead checks whether it’s alive or has changed its UIDs.
另一个可以发送的有趣信号是信号数字0。这个信号实际上不会影响一个子进程,但是会检查它(??)是活的还是已经改变了它的UIDS。
unless (kill 0 => $kid_pid) {
warn "something wicked happened to $kid_pid";
}
Signal number zero may fail because you lack permission to send the signal when directed at a process whose real or saved UID is not identical to the real or effective UID of the sending process, even though the process is alive. You may be able to determine the cause of failure using $! or %! .
信号数字0可能会失败,因为当你的实际或保存的UID与发送过程的真实或有效的UID不相同时,你没有发送信号的权限,即使进程是活的。你可能可以使用 $!或者%!来确定失败的原因。
unless (kill(0 => $pid) || $!{EPERM}) {
warn "$pid looks dead";
}
You might also want to employ anonymous functions for simple signal handlers:
你可能也会想为简单的信号处理器使用匿名方法:
$SIG{INT} = sub { die "\nOutta here!\n" };
SIGCHLD handlers require some special care. If a second child dies while in the signal handler caused by the first death, we won’t get another signal. So must loop here else we will leave the unreaped child as a zombie. And the next time two children die we get another zombie. And so on.