在服务器代码中,每当 Thread A 运行至 monitor = selector.register(socket, :r)
这一行时,线程 A、B 都会阻塞(看起来像是死锁?
请教下阻塞是因为什么原因,以及正确的用法应该是怎么样的?
服务端代码:
# frozen_string_literal: true
require "socket"
require "nio"
def thread_loop
Thread.new do
loop do
yield
end
end
end
def run(host, port)
server = TCPServer.new(host, port)
puts "Listening to #{host}:#{port}"
selector = NIO::Selector.new
threads = []
sockets = []
# Thread A
threads << thread_loop do
ios = IO.select [server]
ios.first.each do |server|
socket = server.accept
sockets << socket
puts "New client #{socket}"
monitor = selector.register(socket, :r)
monitor.value = proc { puts "Got: #{monitor.io.read_nonblock(4096)}" }
end
end
# Thread B
threads << thread_loop do
selector.select do |monitor|
monitor.value.call
end
end
threads.each(&:join)
rescue Interrupt
sockets.each do |socket|
socket.close
selector.deregister(socket)
end
end
run('localhost', 1234)
客户端代码:
# frozen_string_literal: true
require "socket"
def test(host, port, cnt = 10, interval = 1)
sockets = []
cnt.times do
sockets << TCPSocket.new(host, port)
end
loop do
index = rand(cnt)
socket = sockets[index]
puts "Try to send 'Hello from no.#{index} socket!'"
socket << "Hello from no.#{index} socket!"
sleep(interval)
end
rescue Interrupt
puts "Disconnected!"
ensure
sockets.each(&:close)
end
test("localhost", 1234, 3)