Loading...
Searching...
No Matches
TfPyLock Class Reference

Convenience class for accessing the Python Global Interpreter Lock. More...

#include <pyLock.h>

Public Member Functions

TF_API TfPyLock ()
 Acquires the Python GIL and swaps in callers thread state.
 
TF_API ~TfPyLock ()
 Releases Python GIL and restores prior threads state.
 
TF_API void Acquire ()
 (Re)acquires GIL and thread state, if previously released.
 
TF_API void Release ()
 Explicitly releases GIL and thread state.
 
TF_API void BeginAllowThreads ()
 Unlock the GIL temporarily to allow other threads to use python.
 
TF_API void EndAllowThreads ()
 End allowing other threads, reacquiring the lock state.
 

Friends

struct TfPyEnsureGILUnlockedObj
 

Detailed Description

Convenience class for accessing the Python Global Interpreter Lock.

The Python API is not thread-safe. Accessing the Python API from outside the context of Python execution requires extra care when multiple threads may be present. There are various schemes for how this should be done, and the conventions have been changing with Python versions through 2.X.

This class provides a convenient and centralized location for managing the Python Global Interpreter Lock and related Python Thread State.

The easiest way to use this class is to simply create a local variable in any function that will access the Python API. Upon construction, this will acquire the Python lock and establish the correct thread state for the caller. Upon exit from the current scope, when the instance is destroyed, the thread state will be restored and the lock will be released.

void MyFunc()
{
TfPyLock dummy;
...(access Python API)...
}
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:122

If you need to temporarily release the lock during execution, (to perform blocking I/O for example), you can call Release() explicitly, then call Acquire() again to reclaim the lock.

void MyFunc()
{
TfPyLock pyLock;
...(access Python API)...
pyLock.Release(); // let other threads run while we're blocked
...(some blocking I/O or long running operation)...
pyLock.Acquire();
...(more access to Python API)...
}
TF_API void Acquire()
(Re)acquires GIL and thread state, if previously released.
TF_API void Release()
Explicitly releases GIL and thread state.

Note that it IS EXPLICITLY OK to recursively create instances of this class, and thus recursively acquire the GIL and thread state. It is NOT OK to recursively attempt to Acquire() the same instance, that will have no effect and will generate a diagnostic warning.

This class also provides an exception-safe way to release the GIL temporarily for blocking calls, like Py_BEGIN/END_ALLOW_THREADS in the Python C API.

void MyFunc()
{
TfPyLock lock;
...(access Python API)...
lock.BeginAllowThreads(); // totally unlock the GIL temporarily.
...(some blocking I/O or long running operation)...
...(more access to Python API)...
}
TF_API void BeginAllowThreads()
Unlock the GIL temporarily to allow other threads to use python.
TF_API void EndAllowThreads()
End allowing other threads, reacquiring the lock state.

This looks similar to the above example using Release(), but it is different. The Python lock is recursive, so the call to Release() is not guaranteed to actually release the lock, it just releases the deepest lock. In contrast BeginAllowThreads() will fully unlock the GIL so that other threads can run temporarily regardless of how many times the lock is recursively taken.

The valid states and transitions for this class are as follows.

State Valid Transitions

Released Acquire() -> Acquired Acquired Release() -> Released, BeginAllowThreads() -> AllowsThreads AllowsThreads EndAllowThreads() -> Acquired

Note that upon construction the class is in the Acquired state. Upon destruction, the class will move to the Released state.

Warning
Instances of this class should only be used as automatic (stack) variables, or in thread local storage. DO NOT create a single instance that could be shared across multiple threads.

Definition at line 122 of file pyLock.h.

Constructor & Destructor Documentation

◆ TfPyLock()

TF_API TfPyLock ( )

Acquires the Python GIL and swaps in callers thread state.

◆ ~TfPyLock()

TF_API ~TfPyLock ( )

Releases Python GIL and restores prior threads state.

Member Function Documentation

◆ Acquire()

TF_API void Acquire ( )

(Re)acquires GIL and thread state, if previously released.

◆ BeginAllowThreads()

TF_API void BeginAllowThreads ( )

Unlock the GIL temporarily to allow other threads to use python.

Typically this is used to unblock threads during operations like blocking I/O. The lock must be acquired when called.

◆ EndAllowThreads()

TF_API void EndAllowThreads ( )

End allowing other threads, reacquiring the lock state.

BeginAllowThreads must have been successfully called first.

◆ Release()

TF_API void Release ( )

Explicitly releases GIL and thread state.

Friends And Related Function Documentation

◆ TfPyEnsureGILUnlockedObj

friend struct TfPyEnsureGILUnlockedObj
friend

Definition at line 147 of file pyLock.h.


The documentation for this class was generated from the following file: