如何在ruby中运行后台线程?

如何在ruby中运行后台线程?,ruby,multithreading,chat,backgroundworker,Ruby,Multithreading,Chat,Backgroundworker,我是ruby新手,我认为重建一个用C#编写的简单聊天程序是个好主意 我正在使用Ruby 2.0.0 MRI(Matz的Ruby实现) 问题是我想在服务器运行时对简单的服务器命令进行I/O。 这是从示例中获取的服务器。我添加了使用get()获取输入的commands方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程 require 'socket' # Get sockets from stdlib server = TCPServer.open(20

我是ruby新手,我认为重建一个用C#编写的简单聊天程序是个好主意

我正在使用Ruby 2.0.0 MRI(Matz的Ruby实现)

问题是我想在服务器运行时对简单的服务器命令进行I/O。 这是从示例中获取的服务器。我添加了使用get()获取输入的commands方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程

require 'socket'                # Get sockets from stdlib

server = TCPServer.open(2000)   # Socket to listen on port 2000

def commands
    x = 1
    while x == 1
        exitProgram = gets.chomp
        if exitProgram == "exit" || exitProgram == "Exit"
            x = 2
            abort("Exiting the program.")
        end
    end
end

def main
    Thread.start(commands)
    Thread.start(server.accept) 
    loop {                          # Servers run forever

        Thread.start(server.accept) do |client|
        client.puts(Time.now.ctime) # Send the time to the client
        client.puts "Closing the connection. Bye!"
        client.close                # Disconnect from the client
      end
    }
end

main
这是目前为止的客户

require 'socket'      # Sockets are in standard library

hostname = 'localhost'
port = 2000

s = TCPSocket.open(hostname, port)

while line = s.gets   # Read lines from the socket
  puts line.chop      # And print with platform line terminator
end
s.close               # Close the socket when done
gets.chomp

阅读的文档(与此处的
Thread.start
相同)

Thread.start(commands)
运行
commands
方法并将其返回值传递给线程(该线程不执行任何操作)。它是阻塞的,因为在调用
get
时没有启动任何线程。你想要

Thread.start { commands }
这里有一个类似的演示脚本,它的工作原理与您预期的一样

def commands
  while gets.strip !~ /^exit$/i
    puts "Invalid command"
  end
  abort "Exiting the program"
end

Thread.start { commands }

loop do
  puts "Type exit:"
  sleep 2
end

你是使用MRI Ruby还是JRuby?这是铁路吗?这些对线程有影响。我不相信MRI有本机线程。我很确定MRI仍然有一个巨大的“全局解释器锁”;这意味着您将无法获得真正的并发性。谢谢你,我想我会切换到另一个ruby,除非有一个非阻塞版本的gets()?JRuby有真正的线程。它可能对你有用,但启动时间很糟糕。(我只是因为这个原因而取消了一个以上的项目)。如果你在Rails中运行,要小心,因为很多Rails都不是线程安全的,你不需要JRuby。MRI适合聊天服务器。GIL不阻止多重连接。例如,nodejs是单线程的,但可以接受高度并发的请求。您不必手动编写线程,它就是为此而设计的。该页面上有一个EchoServer示例。