class IO
公共实例方法
nonblock {|io| } → object 点击切换源代码
nonblock(boolean) {|io| } → object
以非阻塞模式产生 self。
当参数为 false 时,以阻塞模式产生 self。 代码块执行后,原始模式会被恢复。
static VALUE
rb_io_nonblock_block(int argc, VALUE *argv, VALUE self)
{
int nb = 1;
int descriptor = rb_io_descriptor(self);
if (argc > 0) {
VALUE v;
rb_scan_args(argc, argv, "01", &v);
nb = RTEST(v);
}
int current_flags = get_fcntl_flags(descriptor);
int restore[2] = {descriptor, current_flags};
if (!io_nonblock_set(descriptor, current_flags, nb))
return rb_yield(self);
return rb_ensure(rb_yield, self, io_nonblock_restore, (VALUE)restore);
}
nonblock = boolean → boolean 点击切换源代码
当设置为 true 时,启用流的非阻塞模式;当设置为 false 时,启用阻塞模式。
此方法设置或清除 ios 中文件描述符的 O_NONBLOCK 标志。
大多数 IO 方法的行为不受此标志的影响,因为它们会在 EAGAIN 和部分读取/写入后重试系统调用以完成其任务。(一个例外是 IO#syswrite,它不会重试。)
此方法可用于清除标准 I/O 的非阻塞模式。由于非阻塞方法(read_nonblock 等)会设置非阻塞模式,但不会清除它,因此此方法可按如下方式使用。
END { STDOUT.nonblock = false } STDOUT.write_nonblock("foo")
由于该标志在进程之间共享,并且许多非 Ruby 命令不期望标准 I/O 处于非阻塞模式,因此在 Ruby 程序退出之前清除该标志是安全的。
例如,以下 Ruby 程序会使 STDIN/STDOUT/STDER 处于非阻塞模式。(STDIN、STDOUT 和 STDERR 连接到一个终端。因此,将其中一个设置为非阻塞模式会影响其他两个。)因此,cat 命令尝试从标准输入读取,并导致“Resource temporarily unavailable”错误(EAGAIN)。
% ruby -e '
STDOUT.write_nonblock("foo\n")'; cat
foo
cat: -: Resource temporarily unavailable
清除该标志使 cat 命令的行为正常。(cat 命令等待来自标准输入的输入。)
% ruby -rio/nonblock -e '
END { STDOUT.nonblock = false }
STDOUT.write_nonblock("foo")
'; cat
foo
static VALUE
rb_io_nonblock_set(VALUE self, VALUE value)
{
if (RTEST(value)) {
rb_io_t *fptr;
GetOpenFile(self, fptr);
rb_io_set_nonblock(fptr);
}
else {
int descriptor = rb_io_descriptor(self);
io_nonblock_set(descriptor, get_fcntl_flags(descriptor), RTEST(value));
}
return self;
}
nonblock? → boolean 点击切换源代码
如果 IO 对象处于非阻塞模式,则返回 true。
static VALUE
rb_io_nonblock_p(VALUE io)
{
if (get_fcntl_flags(rb_io_descriptor(io)) & O_NONBLOCK)
return Qtrue;
return Qfalse;
}