With event based programming you essentially just loop and poll, loop and poll...why is this preferred to just blocking? If you're not receiving any events why would you prefer to use select() over just blocking on an accept()?
Normally this question is posed as if event based network programming is makes better use of resources than thread based network programming. The general answer to this question is theoretically no, but practically yes. I recall a paper written by one of the founders of Inktomi who's product later became Apache Traffic Server (Traffic Server is an event based http proxy). Basically, the conclusions were that userspace threads could be as fast as an event based model. They felt that context switching would always make OS level threads slower that event models. There were at the time no production ready userspace threading models that compete with event based models. Finally, they indicated that the conceptual overhead of using a event based model over a thread based model was significant on a large scale application. You have already noticed this.
It is much simpler to just have a bunch of threads each handling the whole connection lifetime than to have an event loop dispatching work based on when some part of the process has to block, when a timer goes off, or who knows what other events. Sadly, at this time, the more complicated approach is the faster.
Note: sorry for not posting a link to the paper, but I cannot seem to find an online source right now. I will try to edit this post with a link later
"better" depends on what you need.
With event based (select/poll/epoll/etc.) IO, you can listen on events from many(thousands) sockets in one thread. This can vastly improve scalability vs using one thread per socket doing blocking operations.
With blocking read/writes/accepts, you can't service several clients concurrently in one thread, you'll have to use at least one thread/process per connection. The drawback here is that this does not scale as much as event based IO. However the programming model becomes much easier.
Sometimes you'll need to call APIs (e.g. to query a backend database) which only provides a blocking API. In such a case, you'll block every other client if you do this in an event based IO loop, and you'll basically have to resort to using thread-per-client anyway - if you need scalability in such cases, it's common to couple an event loop with a worker thread pool, which might make the programming model even harder.
You can use blocking sync IO when:
- You have only one socket active
- Your application doesn't do anything but react to events on the socket
- You don't plan to extend the application
- You don't mind that the user have to kill the application to exit
If any of these are false, you're likely better off with a polling loop.
It isn't a good idea let the program block on an accept. It means that no other operations can be performed until your application will receive some datas.
Even if yout network requirements are very simple and you don't need to send or receive other datas than which for your blocked socket is waiting for, you can't even update your GUI (if you have one ) or receive input from the user.
Generally the point is to use select or threads?
Threads are hard to debug and can create problems regarding concurrent operations. So, unless you explicitly need threads , i'll suggest to use select.
精彩评论