From: Benjohn Barnes Date: 2006-04-29T21:33:35+09:00 Subject: Re: Multiplexed I/O On 29 Apr 2006, at 09:39, Vlad GALU wrote: > I'd like to use Ruby for a quite high performance networking tool. > In practice, writing a multithreaded C/C++ program is not pheasible > due to the large connection pool I plan to manage, which would impose > a very scarce stack size. From what I can see, Ruby's default I/O > semantics are synchronous. One can opt for using IO#select though. > Let's just say synchronous is OK, API-wise. My question is: if I use > one (Ruby) thread per client, would it block the whole Ruby > interpreter while performing blocking I/O ? On my system (FreeBSD) > ruby is linked against libpthread, for a good reason I guess. Could it > be that it splits blocking routines to a separate (POSIX) thread ? If > not, I'll probably end up replacing the select() implementation with > kqueue() calls in the Ruby code. I don't understand why you can't use c++ here, so I guess I'm missing something - my reason for not using c++ would be that I no longer enjoy programming with it :) However... I wrote a server recently that "talked" on numerous sockets to many clients. It would have seemed multi threaded to them, but was in fact single threaded. Here's a very simple version of it. It doesn't handle disconnections at all, but they are easy to add in. I was quite pleased that I could extend the socket objects to be able to polymorphically handle an event on them. I think it'll be pretty high performance, but I've no idea if that's true. It certainly doesn't need to poll, and it doesn't have to jump about in different thread contexts. All the best, Benj require 'socket' $sockets = [] def process_sockets select($sockets)[0].each do |soc| soc.handle_event end end module Server def self.create_server(port) server = TCPServer.new(port) server.extend( self ) end def handle_event $sockets << accept_connection end def accept_connection con = accept con.extend(Connection) end end module Connection def handle_event s = gets.chomp Kernel.puts "#{self} said #{s}" puts "You said #{s}" end end $sockets << Server.create_server(5001) loop {process_sockets}