On Oct 4, 2005, at 4:06 AM, Tanaka Akira wrote: > In article <659657CD-D443-45AD-8006-0458433CF365 / reverberate.org>, > Joshua Haberman <joshua / reverberate.org> writes: > > >> Nonblocking I/O is useful if you are a server with some kind of >> complex, global state, and lots of clients that can act on that >> state. A good example would be a gaming server. If you handle every >> client in its own thread, you need a big, coarse lock around your >> global state. Once you're doing that, what's the point of >> multithreading? It just makes things more complicated, and your >> program's execution more difficult to understand. >> > > I see. > > >> while true >> (read_ready, write_ready, err) = IO.select([A, B, C]) >> read_ready.each { |io| >> output = process(io.read) >> [A, B, C].each { |client| client.write(output) unless client >> == io } >> } >> end >> > > It seems too simplified to explain nonblocking I/O problem. > > O_NONBLOCK is required to avoid that write(2) blocks entire > process. But if write(2) doesn't block due to O_NONBLOCK, > some data are not written. So the result of write(2) should > be checked and remaining data should be try to write later. Yes, the code I posted made some simplifying assumptions. If some of the data was not written, you need to account for that somehow. The options you suggest would work for ensuring that the write happens eventually. But a nice thing about doing everything in a single thread is that you can do better if you choose. Imagine that you start with world W1. You get a message from client A that updates the state of the world to W2. Call DELTA1 the message you have to send to B and C to update them to W2. You try to write DELTA1 to B, but C is not ready. The next time through your event loop, you get a message from client B updating the state of the world to W3. DELTA2 updates W2 to W3, so you send that to A, but C is still not ready. Once C becomes ready, you could send C DELTA1 and DELTA2, or you could be smart and combine those into a single DELTA3 that updates W1 to W3. DELTA3 will likely be smaller than DELTA1 + DELTA2. If you had initially blocked-on-write to send DELTA1, you would not have that option. Josh