Valkka
1.6.1
OpenSource Video Management
|
Classes | |
class | AVThread |
A thread consuming frames and feeding them to various encoders. More... | |
class | LiveThread |
Live555, running in a separate thread. More... | |
class | OpenGLThread |
This class does a lot of things: More... | |
struct | ThreadContext |
An example of information context sent to the Thread inside Thread::SignalContext. More... | |
struct | SignalContext |
Encapsulates data sent by the signal. More... | |
class | Thread |
A class for multithreading with a signaling system. More... | |
class | TestProducerThread |
A demo thread for testing the producer/consumer module for fifos. More... | |
class | TestConsumerThread |
A demo thread for testing the producer/consumer module for fifos. More... | |
Enumerations | |
enum class | Signal { none , exit } |
List of possible signals for the thread. More... | |
+-------------------------+ +-------------------------+-------------------------+ | "backend" thread | | "frontend" thread | | c++ thread | | | Python side method | | running independently | | c++ side | (hold GIL) | | | | | | | | - do stuff & | | <-----|-----+ | | get messages from | [queue] | - send message to | | | queue | | queue >-----|-----+ | | - perform callbacks | | | | | | to python side | | - for backend | continue in Python | | (obtain GIL) | | termination | side & exit | | | | wait for thread | (release GIL) | | | | join | | | | | | | +-------------------------+ +-------------------------+-------------------------+
The frontend's "Python side" API methods are typically tagged with "Call", i.e. they are named "startCall", "stopCall", etc. and are automatically generated from the c++ methods using SWIG.
The backend runs std::thread or pthread whose target method is Thread::mainRun(). The Thread class is a prototype for implementing thread-safe multithreading classes. There are three pure virtual classes, namely:
The method Thread::mainRun() simply does the sequence (1-3)
Since we're dealing here with extending python code in c++ (frontend) and with calling python callbacks from c++ (backend), extra care must be taken with the Python Global Interpreter Lock (GIL)
Frontend methods hold the Python GIL (as they are just normal python methods), which is kept during the whole execution of the c++ "frontend" part (i.e. no Py_BEGIN_ALLOW_THREADS here). These are just fast calls that exit once they have sent a signal to the message queue.
An exception to this rule is the special method Thread::requestStopCall() which, after sending a termination signal to the backend, waits for the thread join (for joining Thread::mainRun()).
If at this moment, the backend is trying to perform a python callback, a deadlock will occur: the frontend is holding the python GIL, while the backend is waiting for its release.
All Python callbacks from the backend after Thread::run() has been exited, should then be performed in the Thread's destructor, and without touching the GIL (destructors are typically evoked by the Python garbage collector, i.e. the GIL is being hold from the Python side)
For practical Thread implementations, see for example LiveThread and OpenGLThread
Thread can be bound to a particular processor core, if needed.