如何在ruby中超时命名管道?

时间:2013-12-17 19:08:13

标签: ruby timeout named-pipes

我看到an article为作者建议了以下代码:

output = open("my_pipe", "w+") # the w+ means we don't block
output.puts "hello world"
output.flush # do this when we're done writing data

和读者:

input = open("my_pipe", "r+") # the r+ means we don't block
puts input.gets # will block if there's nothing in the pipe

openputsgets会阻止该计划吗?是否存在某种超时?可以改变吗?另外,w+如何表示非阻塞呼叫?它转换为哪个open系统调用标志?

3 个答案:

答案 0 :(得分:1)

好的,让我与你分享我对这个世界的看法。正如rogerdpack所述,有两个选项: 1)在阻塞模式下使用select 2)使用非阻塞模式(O_NONBLOCK标志,{{1 }},read_nonblockwrite_nonblock方法)。我没试过,所以这些只是推测。

至于为什么selectopenputs可能阻止线程。 gets调用块,直到至少有一个阅读器和至少一个编写器。这必须是我们需要为open调用指定r+w+的原因。从open输出判断,它们都转换为strace标志。然后必须有一些缓冲区,其中尚未存储接收的数据。这一定是写入方法可能阻塞的原因。读取方法可能会阻塞,因为他们希望有更多数据可用,而不是实际可用。

<强> UPD

  

如果进程尝试从空管道读取,则read(2)将阻塞,直到数据可用。如果进程尝试写入完整管道(见下文),则写入(2)块,直到从管道读取足够的数据以允许写入完成。

     

- http://linux.die.net/man/7/pipe

     

在传递数据之前,必须在两端打开FIFO(读取和写入)。通常,打开FIFO块直到另一端打开。

     

在Linux下,打开FIFO进行读写将在阻塞和非阻塞模式下成功。 POSIX未定义此行为。这可以用来打开FIFO进行写入,而没有可用的读卡器。

     

- http://linux.die.net/man/7/fifo

以下是我提出的实施方案:

O_RDWR

但是对于我手边的问题,我决定忽略这个超时的事情。当管道的另一端没有读卡器(Errno :: ENXIO)时,它可能就足以处理这种情况了:

#!/home/yuri/.rbenv/shims/ruby
require 'timeout'
data = ((0..15).to_a.map { |v|
    (v < 10 ? '0'.ord + v : 'a'.ord + v - 10).chr
} * 4096 * 2).reduce('', :+)
timeout = 10
start = Time.now
open('1.fifo', File::WRONLY | File::NONBLOCK) { |out|
    out.flock(File::LOCK_EX)
    nwritten = 0
    data_len = data.length
    begin
        delta = out.write_nonblock data
        data = data[delta..-1]
        nwritten += delta
    rescue IO::WaitWritable, Errno::EINTR
        timeout_left = timeout - (Time.now - start)
        if timeout_left < 0
            puts Time.now - start
            raise Timeout::Error
        end
        IO.select nil, [out], nil, timeout_left
        retry
    end while nwritten < data_len
}
puts Time.now - start

P.S。感谢您的反馈。

答案 1 :(得分:0)

此页面应该回答您的所有问题...... http://www.ruby-doc.org/core-2.0.0/IO.html

答案 2 :(得分:0)

通常,puts 总是阻止当前线程,因为它们可能必须等待IO完成才能返回。 gets也可以阻止当前线程,因为它将永远读取和读取,直到它到达第一个换行符,然后它将返回它读取的所有内容。 HTH。