类 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;
}