我正在处理一些套接字代码,无法弄清楚为什么在socket上使用autoflush
。它是这样的
my $sock = IO::Socket::Unix(Peer => $socketfilename , Type => SOCK_STREAM)
autoflush $sock 1;
还有
的地方autoflush STDERR 1
autoflush STDOUT 1
用于一般的filehnadles。
它做什么?如果我不使用它会发生或将会发生什么?请举一些实际的例子,以便我理解而不是简单的定义。
答案 0 :(得分:8)
数据通常不会立即在套接字上发送,它会被缓冲到某个点,然后一次性发送。
自动刷新意味着数据直接通过缓冲区然后刷新,而不是保留在缓冲区中,等待其他数据到达并累积。
就这么简单。
没有自动冲洗:
Tick | DATA sent|Socket Buffer| DATA received
.....|..........|.............|..............
1 | XX | XX | (nothing)
2 | yy | yyXX | (nothing)
3 | ZZZ | ZZZyyXX | (nothing)
4 | t | (empty) | tZZZyyXX
自动冲洗:
Tick | DATA sent | Socket Buffer | DATA received
.....|...........|...............|..............
1 | XX | () | XX
2 | yy | () | yy
3 | ZZZ | () | ZZZ
4 | t | () | t
答案 1 :(得分:5)
它绝对没有...因为IO :: Socket :: Unix已经为你做了。
以块的形式发送数据的开销较少,因此文件库会累积数据以在缓冲区中打印,而不是立即发送到系统。只有当累积了4KB或8KB(取决于版本)数据时,才会将实际发送到系统的数据。这被称为"缓冲"。
将句柄的autoflush设置为true会禁用该句柄的缓冲。当您致电print
时,数据会在print
返回之前发送到系统。
看到区别:
$ perl -e'
STDOUT->autoflush($ARGV[0]);
for (0..9) { print $_ x 1024; sleep 1; }
' 1
<whole bunch of 1s>
<one second later: whole bunch of 2s>
<one second later: whole bunch of 3s>
<one second later: whole bunch of 4s>
<one second later: whole bunch of 5s>
<one second later: whole bunch of 6s>
<one second later: whole bunch of 7s>
<one second later: whole bunch of 8s>
<one second later: whole bunch of 9s>
$ perl -e'
STDOUT->autoflush($ARGV[0]);
for (0..9) { print $_ x 1024; sleep 1; }
' 0
# Before Perl 5.14:
<four seconds later: whole bunch of 0s, 1s, 2s and 3s>
<four seconds later: whole bunch of 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>
# Perl 5.14+
<eight seconds later: whole bunch of 0s, 1s, 2s, 3s, 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>
IO :: Socket :: *启用了 autoflush
,因为套接字大部分时间都需要它。套接字通常用于交互式通信。请求,回复,请求,回复等。想象一下如果请求被卡在缓冲区中会发生什么......你将永远等待回复!
答案 2 :(得分:4)
来自IO::Handle:
sub autoflush {
my $old = new SelectSaver qualify($_[0], caller);
my $prev = $|;
$| = @_ > 1 ? $_[1] : 1;
$prev;
}
没有魔力。
from:
$ |
如果设置为非零,则立即强制刷新并在每次写入或之后 在当前选定的输出通道上打印。默认值为0 (无论通道是否真的由系统缓冲或 不;
$|
仅告诉您是否已明确要求Perl进行刷新 每次写完后)。如果输出,STDOUT通常会进行行缓冲 到终端和否则缓冲块。设置此变量是 主要用于输出管道或插槽时,例如 当您在rsh下运行Perl程序并想要查看时 输出正在发生。这对输入缓冲没有影响。看到 getc为此。有关如何选择输出的信息,请参阅select 渠道。另请参阅IO::Handle。