|
1 |
| -# Overview |
| 1 | +# Table of Contents |
| 2 | +* [Overview](#overview) |
| 3 | +* [Installation](#install) |
| 4 | +* [Specialities](#special) |
| 5 | +* [Credits](#credits) |
| 6 | + |
| 7 | +# Overview <a name="overview"/> |
2 | 8 | This example demonstrates how to use shared memory (via [`QSharedMemory`](https://doc.qt.io/qt-5/qsharedmemory.html)) and a system-wide semaphore (via [`QSystemSemaphore`](https://doc.qt.io/qt-5/qsystemsemaphore.html)) between a C++ application (the consumer on default) and a Python application (the producer on default) in Qt5. The behavior (producer vs. consumer) can be controlled in both sources via the `CONSUMER` define/variable: 0 means producer, 1 means consumer. Both apps print some logging information to the standard output.
|
3 | 9 |
|
4 | 10 | Both for Python (see `prodcon_ipc` package) and C++ (see `*_ipc.{h,cpp}`files in `src/` directory), the **relevent functionality is encapsulated in dedicated classes to ease re-usability**.
|
5 | 11 |
|
6 | 12 | In the accompanying example applications, the producer "produces" an image by loading them from a file from disk (when the user triggers it) and the consumer "consumes" these images by displaying them in the UI. The C++ application is designed in a threaded fashion so that it spawns a separate thread which waits for the system semaphore to be signaled to not block the UI thread. The Python consumer however (still) blocks when the user clicks the button at the bottom of the UI to activate the waiting (blocking). (It blocks until an image was "produced".)
|
7 | 13 |
|
8 |
| -# Installation |
| 14 | +# Installation <a name="install"/> |
9 | 15 | Install Qt5, PyQt5, CMake and a compiler (gcc or clang) on your system. Either compile the sources manually or use the provided `build.sh` script to compile and run it. The compiled C++ application will be placed in `build/shared_memory_cpp`. The Python application is `shared_memory.py`.
|
10 | 16 |
|
11 | 17 | Tested with PyQt v5.10.1, Qt v5.9.5 and GCC v7.5.0 on Ubuntu 18.04.4 LTS.
|
12 | 18 |
|
13 |
| -# Specialities |
| 19 | +# Specialities <a name="special"/> |
14 | 20 | There are some things to note:
|
15 | 21 | - The system-semaphores to be used for the [producer-consumer problem](https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem) are always reset to their defaults which allows for starting the apps in any order. However, this also has the consequence that when, for instance, the Python app was started first and already "produced" an image, it will be removed/lost if the C++ app is started afterwards. This can be avoided by adjusting the semaphore creation (using `QSystemSemaphore::Open` instead of `QSystemSemaphore::Create`, see [docs](https://doc.qt.io/qt-5/qsystemsemaphore.html#AccessMode-enum)) and depends on the actual interaction (design) of the applications.
|
16 | 22 | - Shared memory is tricky in general because if an app crashes, the [shared memory might not be removed properly](https://stackoverflow.com/questions/42549904/qsharedmemory-is-not-getting-deleted-on-application-crash). If that's the case, restarting an app might cause it to fail creating the shared memory (as its already existing). To avoid this, the apps try to re-attach the memory if this happens (see e.g. `ProducerIPC::begin()`). It also tries to avoid exceptions/errors when the shared memory is used.
|
17 | 23 | - As an addition to the previous problem, a `shared_memory.key` file option has been added, allowing one to also (alternatively) specify the unique name of the shared memory in that file. It is used only if the file exists (in the app directory) and allows one to temporarily change the shared memory's name.
|
18 | 24 | - If multiple data/images should be stored in shared memory, the number of free slots in the semaphore needs to be increased (see `sem_empty`in `abstract_ipc.{cpp,py}`.
|
19 | 25 | - Finally, take note about how shared memory is [released differently](https://doc.qt.io/qt-5/qsharedmemory.html#details) across operating systems.
|
20 | 26 |
|
21 |
| -# Credits |
| 27 | +# Credits <a name="credits"/> |
22 | 28 | Based on:
|
23 | 29 | - https://code.qt.io/cgit/qt/qtbase.git/tree/examples/corelib/ipc/sharedmemory?h=5.14
|
24 | 30 | - https://github.com/baoboa/pyqt5/tree/master/examples/ipc/sharedmemory
|
0 commit comments