Valkka  1.6.1
OpenSource Video Management
Classes | Enumerations
multithreading
Collaboration diagram for multithreading:

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...
 

Detailed Description

+-------------------------+         +-------------------------+-------------------------+           
| "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:

  1. Thread::preRun() allocates necessary resources for the Thread (if not reserved at constructor time)
  2. Thread::run() uses the resources and does an infinite loop. It listens to requests and executes Thread's methods
  3. Thread::postRun() deallocates resources

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.

Enumeration Type Documentation

◆ Signal

enum Signal
strong

List of possible signals for the thread.

Naming convention: if your Thread class is SomeThread, then name the Signal to SomeSignal