相关疑难解决方法(0)

通过SO_RCVTIMEO套接字选项在Ruby中设置套接字超时

我试图通过SO_RCVTIMEO套接字选项在Ruby中使套接字超时,但它似乎对任何最近的*nix操作系统没有影响.

使用Ruby的Timeout模块不是一个选项,因为它需要为每个超时生成并加入线程,这可能会变得很昂贵.在需要低套接字超时且具有大量线程的应用程序中,它基本上会导致性能下降.许多地方都已经注意到这一点,包括Stack Overflow.

我读过迈克·佩勒姆对这个问题的优秀岗位在这里,并在努力把问题缩小到可运行代码的一个文件中创建一个TCP服务器的一个简单的例子,将收到的请求,等待在请求中发送的时间量和然后关闭连接.

客户端创建套接字,将接收超时设置为1秒,然后连接到服务器.客户端告诉服务器在5秒后关闭会话,然后等待数据.

客户端应在一秒钟后超时,但在5之后成功关闭连接.

#!/usr/bin/env ruby
require 'socket'

def timeout
  sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)

  # Timeout set to 1 second
  timeval = [1, 0].pack("l_2")
  sock.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, timeval

  # Connect and tell the server to wait 5 seconds
  sock.connect(Socket.pack_sockaddr_in(1234, '127.0.0.1'))
  sock.write("5\n")

  # Wait for data to be sent back
  begin
    result = sock.recvfrom(1024)
    puts "session closed"
  rescue Errno::EAGAIN
    puts "timed out!"
  end
end

Thread.new do
  server = TCPServer.new(nil, 1234)
  while (session = server.accept) …
Run Code Online (Sandbox Code Playgroud)

ruby sockets io timeout tcp-ip

19
推荐指数
3
解决办法
6793
查看次数

如何使用File#flock对独占锁进行非阻塞请求?

我该如何申请非阻塞锁?

为什么在单独尝试锁定文件时,Ruby的File#flock不能按预期工作?锁定块中的文件不是解决此问题的正确方法,因为重点是显示锁定持久锁的行为.在块中使用File#flock会在块退出时释放锁定,因此它不能正确显示问题.

File#flock以各种方式失败,尤其是在请求非阻塞锁定时.一些例子如下.

File#flock失败的例子

  • 使用多个独占锁时无限等待,因为#flock不提供超时锁定请求的方法.

    # First lock succeeds.
    f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f1.flock(File::LOCK_EX)
    # => 0
    
    # This never returns.
    f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f2.flock(File::LOCK_EX)
    
    Run Code Online (Sandbox Code Playgroud)
  • 在文件被独占锁定时请求非阻塞锁定会导致无效的参数异常.

    f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f1.flock(File::LOCK_EX)
    # => 0
    
    f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f2.flock(File::LOCK_NB)
    # => Errno::EINVAL: Invalid argument - foo
    
    Run Code Online (Sandbox Code Playgroud)
  • 文档说#flock"根据locking_constant(逻辑或下表中的值)锁定或解锁文件." 但是,Logical OR会提升Errno::EINVALErrno::EBADF取决于平台.

    f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f1.flock(File::LOCK_EX)
    # => 0
    
    f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
    f2.flock(File::LOCK_NB || File::LOCK_EX)
    # …
    Run Code Online (Sandbox Code Playgroud)

ruby locking flock fcntl

11
推荐指数
1
解决办法
4791
查看次数

标签 统计

ruby ×2

fcntl ×1

flock ×1

io ×1

locking ×1

sockets ×1

tcp-ip ×1

timeout ×1