[Python-ideas] The async API of the future: Twisted and Deferreds
Nick Coghlan
ncoghlan at gmail.com
Sat Oct 13 17:46:09 CEST 2012
On Sat, Oct 13, 2012 at 8:52 PM, Itamar Turner-Trauring
<itamar at futurefoundries.com> wrote:
> def addToCounter():
> counter.value = counter.value + (yield getResult())
This is buggy code for the reasons you state. However, only improperly
*embedded* yields have this problem, yields that are done in a
dedicated assignment statement are fine:
def addToCounter():
result = yield getResult()
# No race condition here, as we only read the counter *after*
receiving the result
counter.value = counter.value + result
(You can also make sure they're the first thing executed as part of a
larger expression, but a separate assignment statement will almost
always be clearer)
> In a Deferred callback, on the other hand, you know the only things that are
> going to run are functions you call. In so far as it's possible, what
> happens is under control of one function only. Less pretty, but no potential
> race conditions:
>
> def add(result):
> counter.value = counter.value + result
> getResult().addCallback(add)
This is not the same code you wrote above in the generator version.
The callback equivalent of the code you wrote is this:
bound_value = counter.value
def add(result):
counter.value = bound_value + result
getResult().addCallback(add)
The generator version isn't magic, people still need to know what
they're doing to properly benefit from the cooperative multithreading.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list