I have a function inside a threaded object, this function accepts several parameters and I don't know if when many threads try to use this function this threads will change the parameter values of another thread?
I can use a lock but after the parameters have been assigned.
If the parameters are stored in the stack I guess they will live inside each threads stack but if they live in heap how can avoid threads changing another threads function parameters?
Function parameters are put on the stack, and each thread has its own stack. You don't have to worry about their thread-safety.
However, all Python objects are stored on the heap; the stack merely holds references to such objects. If multiple threads are accessing one such mutable object they can still interfere with one another if the access is not synchronised somehow. This has nothing to do with how functions are called however.
Related
While trying to figure out this answer I see from the documentation that every stack frame has an f_globals member.
Is that designed to be manipulated on a per-callee basis?
I want to advertise a local variable to callees of a function, in a sort of "while we're within this call tree, this is the context decorators and utilities will use" way, without having to modify every function in the potential call graph to pass this along. It's not a great decorator when you have to rewrite the decorated function, after all.
So here's what I think I've learned so far:
The call stack can contain different values of r_globals for each frame because each function has "global" state that is shared within the module in which it is defined and not the whole execution state. Since calls can cross between modules, r_globals can be different in every frame.
Even if you create a new module and copy a function into it, __globals__ is a read-only member of that function object, so when you call it its globals revert back to the original module where it was first defined, not the modified globals of its adopted parent.
Similarly, if you use exec() with modified globals, or if you can build your own copy of the callee code with modified __globals__ you'll only get one layer deep before a subsequent call reverts back to that function's original view of its globals.
It looks like the intended solution to this problem is context variables, which addresses some problems that thread-local storage fails to handle.
If you have a function which creates variables from values(associated to variables outside of the function) are these new variables localised to the particular thread running the function?
Are you asking about local variables? I don't know the exact details of how Python is implemented, but conceptually, Every time a function is called, an activation record (AR) is created. The AR is a data structure that contains the arguments, and all of the local variables for that one specific call. The AR is destroyed when the call for which it was created returns.
That means, not only do concurrent calls to the same function in different threads each have their own AR, but also; if there are recursive calls to the function in the same thread, those calls also each have their own AR containing their own private versions of the local variables.
P.S.; Don't forget though, that a variable is not the same thing as an object. Objects in Python (including tuples, lists, dictionaries, etc. as well as program-defined class objects) don't live in variables at all. They only exist on the heap, and when we say that such-and-such variable "contains" an object, that's a lazy way of saying that the variable refers to the object.
It often can happen that local variables from two or more different activation records will refer to the same shared object.
I would like to use thread local storage across multiple classes.
But threading.local() gets me a new instance of storage every time I call it. Is there a way to use
threading.local().__setattr__('r_id', uuid.uuid4())
And there an equivalent of somehow to access in a completely different class ?
threading.local().__getattribute__('r_id')
Here you can find your ans
https://stackoverflow.com/questions/104983/what-is-thread-local-storage-in-python-and-why-do-i-need-it
Here you can find something interesting as well
Efficient way to determine whether a particular function is on the stack in Python
In a python reference manual said that
A code block is executed in an execution frame. A frame contains some
administrative information (used for debugging) and determines where
and how execution continues after the code block’s execution has
completed.
and
Frame objects represent execution frames. They may occur
in traceback objects
But I don't understanf how frame does work. How can I get an acces to a current frame object? When is frame object creating? Is the frame object created everytime when a code of new block is strarting to execute?
These frames are representations of the stack frames created by function calls. You should not need to access them in normal programming. A new frame is indeed created every time a function is called, and destroyed when it exits or raises an uncaught exception. Since function calls can go many levels deep your program ends up with a bunch of nested stack frames, but it's not good programming practice (unless you are writing a debugger or similar application) to mess about with the frames even though Python does make them available.
It is important to understand frames in Python 3, especially if you maintain production code that is sensitive to memory usage, such as deep learning models.
Frames are objects that represent areas of memory where local variables are stored when a function is called. They can be stored and manipulated, which is what debuggers do. Understanding how frames are handled by python can help you avoid memory leaks.
Each time a function is called, a new frame is created to hold the function's variables and parameters. These frames are normally destroyed when the function finishes executing normally. However, if an exception is raised, the associated frame and all parent frames are stored in a traceback object, which is an attribute of the Exception object (__traceback__). This can cause memory leaks if the Exception object live for a long time, because they will hold onto the frames and all associated local variables are not going to be garbage collected.
This matter quite a lot.
For example it is one reason why you need to call the close method on file objects even if you don't create reference cycles, because the file object may be referenced by a traceback object stored on an Exception. This exclude file from being garbage collected even after it goes out of scope.
The issue is worse in interactive python shells like (Jupyter) where each unhandled exceptions ends up leaving forever in few places. I'm working on a way to clear that up hence I've found this issue.
In Python, the types module provides the FrameType and TracebackType types, which represent frames and tracebacks, respectively. However, you cannot instantiate these types directly. https://docs.python.org/3/library/types.html#types.FrameType
The tracback attribute was introduced in python 3 with PEP 3134, it goes a bit on ramification of this change in details, so it is a good read for curious.
Basic using threads question here.
I'm modifying a program with 2 thread classes and I'd like to use a function defined in one class in both classes now.
As a thread newbie (only been playing with them for a few months) is it OK to move the function out of the thread class into the main program and just call it from both classes or do I need to duplicate the function in the other class that doesn't have it?
regards
Simon
You can call the same function from both threads. The issue to be aware of is modifying shared data from two threads at once. If the function attempts to modify the same data from both threads, you will end up with an unpredictable program.
So the answer to your question is, "it depends what the function does."
It certainly won't help to copy the function into both thread classes. What matters is what the function does, not how many copies of the code there are.
might wanna checkout thread locking. threads operating on 1 function/method can 'lock' that function in many languages so other threads can't access it at the same time. http://en.wikipedia.org/wiki/Lock_(computer_science)