select RBITS, WBITS, EBITS, TIMEOUT
四个参数的 select 和前面那个 select 完全无关。这个操作符用于发现你的文件描述符中那个(如果有的话)已经准备好做输入或者输出了,或者报告一个例外条件。(这样就避免你做轮询。)它用你声明的位掩码调用 select(2) 系统调用,你可以用 fileno 和 vec 构造这个位掩码,象这样:
$rin = $win = $ein = ""; vec($rin, fileno(STDIN), 1) = 1; vec($win, fileno(STDIN), 1) = 1; $ein = $rin | $win;
如果你想在许多文件句柄上 select,你可能会写这样的子过程:
sub fhbits {
my @fhlist = @_;
my $bits;
for (@fhlist) {
vec($bits, fileno($_), 1) = 1;
}
return $bits;
}
$rin = fhbits(qw(STDIN TTY MYSOCK));
如果你想重复使用同样的位掩码(这样做更高效),常用的惯用法是:
($nfound, $timeleft) =
select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
或者阻塞住直到任意文件描述符准备好:
$nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
如你所见,在标量环境中调用 select 只返回 $nfound,找到的准备好的文件描述符数量。
可以用 $wout=$win 技巧是因为一个赋值语句的数值是它自身的左边,因此 $wout 先被赋值删除,然后又被 select 删除,而 $win 不会变化。
这些参数任何一个都可以是 undef,这个时候它们被忽略。如果 TIMEOUT 不是 undef,那么就是以秒计,而且可以是分数。(超时时间为 0 的效果就是轮询。)不是所有实现都能返回 $timeleft。如果不能返回 $timeleft,那么它总是返回等于你提供的 $timeout 的 $timeleft。
标准的 IO::Select 模块提供了 select 的更加友善的接口,主要是因为它为你做了所有你能用的位掩码。
select 的一个应用就是实现比 sleep 分辨率更好的睡眠。要实现这个目的,声明所有位映射为 undef。因此,如果要睡眠(至少)4.75 秒钟,用:
select undef, undef, undef, 4.75;
(在一些非 Unix 系统上,三个 undef 的形式可能不能用,你可能需要为一个有效的描述符至少伪装一个位掩码,而那个描述符可以是从来准备不好的。)
我们不应该把缓冲的 I/O(比如 read 或 )和 select 混在一起用,除了 POSIX 允许的以外,而且就算 POSIX 允许,也只能在真正的 POSIX 系统上使用。这时应该用 sysread。
semctl ID, SEMNUM, CMD, ARG
这个函数调用 System V IPC 函数 semctl(2)。你可能得先说 use IPC::SysV 以获取正确的常量定义。如果 CMD 是 IPC_STAT 或者 GETALL,那么 ARG 必须是一个它可以保存返回的 semid_ds 结构或信号灯数值数组的变量。和 ioctl 和 fcntl 一样,返回值用 undef 代表错误,“0 but true”代表零,其他情况则返回实际数值。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-3.html
太完美了
才是最明智者
体育老师教你的历史