类 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 命令尝试从标准输入读取,这会导致“资源暂时不可用”错误(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; }