gpt4 book ai didi

ruby - IO#read 在非阻塞套接字上阻塞?

转载 作者:数据小太阳 更新时间:2023-10-29 07:37:07 24 4
gpt4 key购买 nike

ruby 1.8.7。我正在调用已打开并连接到的套接字上的读取:

socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(mp.port, mp.ip_address.ip)
begin
socket.connect_nonblock(sockaddr)
[...]

通过调用 select() 确认连接,然后第二次连接以查找 Errno::EISCONN。

然后我用 0 超时再次调用 select,如果返回值不是 nil,我从套接字中读取,首先确认它设置了 O_NONBLOCK:

 rc = select([socket], nil, nil, 0)
puts " select returned: #{rc.pretty_inspect}"
if rc
begin
puts " reading: #{socket} nonblock: #{socket.fcntl(Fcntl::F_GETFL) & Fcntl::O_NONBLOCK}"
response = socket.read
puts " done reading"
[...]

这一切都在每分钟循环一次。第一次循环的输出是:

select returned: [[#<Socket:0xb6e0dcb8>], [], []]
reading: #<Socket:0xb6e0dcb8> nonblock: 2048
done reading

但是第二次循环在这里挂起:

select returned: [[#<Socket:0xb6e0dcb8>], [], []]
reading: #<Socket:0xb6e0dcb8> nonblock: 2048

将 gdb 附加到进程会显示此回溯:

__kernel_vsyscall () 中的 0xffffe410
1 0xb7e5539d in select () from/lib/tls/i686/cmov/libc.so.6
2 0x08064368 in rb_thread_schedule () at eval.c:11020
3 0x080785bb in io_fread (

用对 rcvfrom_nonblock 的调用替换对 read 的调用是有效的,有趣的是它没有获得 EAGAIN,它实际上读取数据(正如您所期望的那样从 select 返回)。

有什么想法吗?

史蒂夫

最佳答案

你期待答案“IO#read 不尊重底层文件描述符上设置的标志”是正确的:

ruby 1.9.3 IO#read

Note that this method behaves like fread() function in C. If you need the behavior like read(2) system call, consider readpartial, read_nonblock and sysread.

感谢您使用 1.8,但是

  • 您看到进程卡在 io_fread 中,并且
  • IO#read_nonblock 在 1.8 中也可用。

关于ruby - IO#read 在非阻塞套接字上阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3967807/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com