"Mikael Brockman" <mikael / phubuh.org> schrieb im Newsbeitrag
news:87brdkzjd8.fsf / igloo.phubuh.org...
> "Robert Klemme" <bob.news / gmx.net> writes:
>
> > "Mikael Brockman" <mikael / phubuh.org> schrieb im Newsbeitrag
> > news:87r7mgzo8x.fsf / igloo.phubuh.org...
> > > "Robert Klemme" <bob.news / gmx.net> writes:
> > >
> > > > "Mikael Brockman" <mikael / phubuh.org> schrieb im Newsbeitrag
> > > > news:87vfbszr5m.fsf / igloo.phubuh.org...
> > > >
> > > > > Blocking I/O is really easy to use.  But when you use it to
> > > > > write servers, you run into problems: you can't run two blocking
> > > > > syscalls simultaneously.  So if you're writing a huge file to
> > > > > some guy, every other client is stalled, and no one new can
> > > > > connect.  Unacceptable, for many types of servers.  They need
> > > > > non-blocking I/O.
> > > > >
> > > > > Non-blocking I/O is a lot more annoying to use.  Instead of
> > > > > going
> > > >
> > > > <snip/>
> > > >
> > > > > It'll run in one thread.  Multiplexer handles the select(3)
calls.
> > > >
> > > > What is the advantage over a solution with threads?  IOW, why
> > > > should I use multiplexer over individual threads per connection?
> > >
> > > Since Ruby's threads aren't native, you can't do I/O from several at
> > > a time.
> >
> > That's not true.
> >
> > >  So one IO#read call blocking for a long time will block the other
> > > threads, too.
> >
> > Also wrong: execute this script
> > [snip]
>
> Sorry: faulty generalization.  The problem is demonstrated in this
> script:
>
> | require 'socket'
> |
> | server = TCPServer.new 12345
> |
> | t_a = Thread.start do
> |   a = server.accept
> |   data = "foo" * 10000000
> |   a << data
> |   a.close
> | end
> |
> | b = server.accept
> | b << "b"
> | b.close
> |
> | t_a.join
>
> The second client isn't accepted until the huge batch of data is sent.
> I guess you could solve the problem by splitting it into a bunch of
> smaller batches.
>
> Another appeal could be that by keeping it single-threaded, you have
> fewer concurrency issues to worry about.

The typical pattern for TCPserver looks different: You create a thread per
accepted connection.

require 'socket'

server = TCPServer.new 12345

loop do
  Thread.new(server.accept) do |a|
    begin
      data = "foo" * 10000000
      a << data
    ensure
      a.close
    end
  end
end

Regards

    robert