[Python-ideas] Tulip / PEP 3156 event loop implementation question: CPU vs. I/O starvation (original) (raw)
Guido van Rossum guido at python.org
Sat Jan 12 00:41:05 CET 2013
- Previous message: [Python-ideas] csv dialect enhancement
- Next message: [Python-ideas] Tulip / PEP 3156 event loop implementation question: CPU vs. I/O starvation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Here's an interesting puzzle. Check out the core of Tulip's event loop: http://code.google.com/p/tulip/source/browse/tulip/unix_events.py#672
Specifically this does something like this:
poll for I/O, appending any ready handlers to the _ready queue
append any handlers scheduled for a time <= now to the _ready queue
while _ready: handler = _ready.popleft() call handler
It is the latter loop that causes me some concern. In theory it is possible for a bad callback to make this loop never finish, as follows:
def hogger(): tulip.get_event_loop().call_soon(hogger)
Because call_soon() appends the handler to the _ready queue, the while loop will never finish.
There is a simple enough solution (Tornado uses this AFAIK):
now_ready = list(_ready) _ready.clear() for handler in now_ready: call handler
However this implies that we go back to the I/O polling code more frequently. While the I/O polling code sets the timeout to zero when there's anything in the _ready queue, so it won't block, it still isn't free; it's an expensive system call that we'd like to put off until we have nothing better to do.
I can imagine various patterns where handlers append other handlers to the _ready queue for immediate execution, and I'd make such patterns efficient (i.e. the user shouldn't have to worry about the cost of the I/O poll compared to the amount of work appended to the _ready queue). It is also convenient to say that a hogger that really wants to hog the CPU can do so anyway, e.g.:
def hogger(): while True: pass
However this would pretty much assume malice; real-life versions of the former hogger pattern may be spread across many callbacks and could be hard to recognize or anticipate.
So what's more important? Avoid I/O starvation at all cost or make the callbacks-posting-callbacks pattern efficient? I can see several outcomes of this discussion: we could end up deciding that one or the other strategy is always best; we could also leave it up to the implementation (but then I still would want guidance for what to do in Tulip); we could even decide this is so important that the user needs to be able to control the policy here (though I hate having many configuration options, since in practice few people bother to take control, and you might as well have hard-coded the default...).
Thoughts? Do I need to explain it better?
-- --Guido van Rossum (python.org/~guido)
- Previous message: [Python-ideas] csv dialect enhancement
- Next message: [Python-ideas] Tulip / PEP 3156 event loop implementation question: CPU vs. I/O starvation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]