[Python-ideas] Keyword only argument on function call
Ethan Furman
ethan at stoneleaf.us
Wed Sep 12 09:59:44 EDT 2018
On 09/12/2018 05:17 AM, Steven D'Aprano wrote:
> Indeed. Each time you call locals(), it returns a new dict with a
> snapshot of the current local namespace. Because it all happens inside
> the same function call, no external thread can poke inside your current
> call to mess with your local variables.
>
> But that's different from setting function.__params__ to passed in
> arguments. By definition, each external caller is passing in its own set
> of arguments. If you have three calls to the function:
>
> function(a=1, b=2) # called by A
> function(a=5, b=8) # called by B
> function(a=3, b=4) # called by C
>
> In single-threaded code, there's no problem here:
>
> A makes the first call;
> the interpreter sets function.__params__ to A's arguments;
> the function runs with A's arguments and returns;
>
> only then can B make its call;
> the interpreter sets function.__params__ to B's arguments;
> the function runs with B's arguments and returns;
>
> only then can C make its call;
> the interpreter sets function.__params__ to C's arguments;
> the function runs with C's arguments and returns
>
>
> but in multi-threaded code, unless there's some form of locking, the
> three sets can interleave in any unpredictable order, e.g.:
>
> A makes its call;
> B makes its call;
> the interpreter sets function.__params__ to B's arguments;
> the interpreter sets function.__params__ to A's arguments;
> the function runs with B's arguments and returns;
> C make its call;
> the interpreter sets function.__params__ to C's arguments;
> the function runs with A's arguments and returns;
> the function runs with C's arguments and returns.
>
>
> We could solve this race condition with locking, or by making the pair
> of steps:
>
> the interpreter sets function.__params__
> the function runs and returns
>
> a single atomic step. But that introduces a deadlock: once A calls
> function(), threads B and C will pause (potentially for a very long
> time) waiting for A's call to complete, before they can call the same
> function.
>
> I'm not an expert on threaded code, so it is possible I've missed some
> non-obvious fix for this, but I expect not. In general, solving race
> conditions without deadlocks is a hard problem.
I believe the solution is `threading.local()`, and Python would
automatically use it in these situations.
--
~Ethan~
More information about the Python-ideas
mailing list