
On Sat, Jun 27, 2015 at 12:51 AM, Paul Sokolovsky <pmiscml@gmail.com> wrote:
Some say "convenient", others say "dangerous".
Consider:
buf = bytearray(MULTIMEGABYTE)
In one function you do:
socket.write(buf),
in another function (coroutine), you keep mutating buf.
So, currently in Python you know if you do:
socket.write(buf)
Then you know it will finish without interruptions for entire buffer. And if you write:
await socket.write(buf)
then you know there may be interruption points inside socket.write(), in particular something else may mutate it while it's being written. With threads, you always have to assume this last scenario, and do extra effort to protect against it (mutexes and stuff).
Hmm. I'm not sure how this is a problem; whether you use 'await' or not, using a mutable object from two separate threads or coroutines is going to have that effect. The way I'm seeing it, coroutines are like cooperatively-switched threads; you don't have to worry about certain operations being interrupted (particularly low-level ones like refcount changes or list growth), but any time you hit an 'await', you have to assume a context switch. That's all very well, but I'm not sure it's that big a problem to accept that any call could context-switch; atomicity is already a concern in other cases, which is why we have principles like EAFP rather than LBYL. There's clearly some benefit to being able to assume that certain operations are uninterruptible (because there's no 'await' anywhere in them), but are they truly so? Signals can already interrupt something _anywhere_:
import signal def mutate(sig, frm): ... print("Mutating the global!") ... lst[5] = 0 ... signal.signal(signal.SIGALRM, mutate) <Handlers.SIG_DFL: 0> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9] def spin(): ... while True: ... lst[0] += lst[5] ... lst[2] += lst[0] ... lst[4] += lst[6] ... lst[6] -= lst[2] ... if not lst[5]: ... print("Huh???") ... break ... signal.alarm(2) 0 spin() Mutating the global! Huh???
Any time you're using mutable globals, you have to assume that they can be mutated out from under you. Coroutines don't change this, so is there anything gained by knowing where you can't be interrupted by one specific possible context switch? ChrisA