[issue24020] threading.local() must be run at module level (doc improvement)

Ethan Furman report at bugs.python.org
Wed Apr 22 00:11:31 CEST 2015


Ethan Furman added the comment:

Here's a basic outline of what I was trying:
-------------------------------------------

CONTEXT = None

class MyFUSE(Fuse):

   def __call__(self, op, path, *args):
      global CONTEXT
      ...
      CONTEXT = threading.local()
      # set several CONTEXT vars
      ...
      # dispatch to correct function to handle 'op'

Under stress, I would eventually get threading.local objects that were missing attributes.

Points to consider:
- I have no control over the threads; they just arrive wanting their
  'op's fulfilled
- the same thread can be a repeat customer, but with the above scenario they would/should
  get a new threading.local each time

Hmmm... could my problem be that even though function locals are thread-safe, the globals are not, so trying to create a threading.local via a global statement was clobbering other threading.local instances?  While that would make sense, I'm still completely clueless why having a single global statement, which (apparently) creates a single threading.local object, could be distinct for all the threads... unless, of course, it can detect which thread is accessing it and react appropriately.  Okay, that's really cool.

So I was doing two things wrong:
- calling threading.local() inside a function (although this would
  probably work if I then passed that object around, as I do not
  need to persist state across function calls -- wait, that would
  be the same as using an ordinary, function-local dict, wouldn't
  it?)
- attempting to assign the threading.local object to a global
  variable from inside a function (this won't work, period)

Many thanks for helping me figure that out.

Paul, in your SO answer you state:
---------------------------------
Just like an ordinary object, you can create multiple threading.local instances in your code. They can be local variables, class or instance members, or global variables.

- Local variables are already thread-safe, aren't they?  So there
  would be no point in using threading.local() there.
- Instance members (set from __init__ of someother method): wouldn't
  that be the same problem I was having trying to update a
  non-threadsafe global with a new threading.local() each time?

It seems to me the take-away here is that you only want to create a threading.local() object /once/ -- if you are creating the same threading.local() object more than once, you're doing it wrong.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue24020>
_______________________________________


More information about the Python-bugs-list mailing list