Shared Memory Usage Between Qt UI and A.exe
🧩 Application Architecture Overview
| Component | Role |
|---|---|
A.exe |
External process writing status/log/values to shared memory |
| Qt UI | GUI process that starts/stops A.exe, reads its output/status from shared memory |
| Shared Memory | Used for bidirectional communication (if needed), e.g., variables or status flags |
| QSystemSemaphore | Synchronizes access to shared memory to avoid race conditions |
📦 Shared Memory Setup
1. Define Shared Data Structure (common to both)
// shared_data.h
#ifndef SHARED_DATA_H
#define SHARED_DATA_H
struct SharedData {
int statusCode;
float someValue;
char log[512];
};
#endif
2. Shared Memory and Semaphore Keys
Use the same names in both A.exe and the Qt app:
const QString SHARED_MEM_KEY = "MySharedMemoryKey";
const QString SEMAPHORE_KEY = "MySharedMemorySemaphore";
const int SHARED_MEM_SIZE = sizeof(SharedData);
🏗️ Where is Shared Memory Created?
-
The Qt UI should create the shared memory on startup (before starting
A.exe). -
A.exewill just attach to it.
In Qt UI:
QSharedMemory sharedMemory(SHARED_MEM_KEY);
QSystemSemaphore semaphore(SEMAPHORE_KEY, 1);
// Create shared memory segment
if (!sharedMemory.create(SHARED_MEM_SIZE)) {
if (sharedMemory.error() == QSharedMemory::AlreadyExists) {
sharedMemory.attach(); // Fallback
}
}
✏️ Writing to Shared Memory (A.exe)
In A.exe (after attaching):
QSharedMemory sharedMemory(SHARED_MEM_KEY);
QSystemSemaphore semaphore(SEMAPHORE_KEY, 1);
if (!sharedMemory.attach()) {
// handle error
}
semaphore.acquire(); // Lock semaphore
sharedMemory.lock(); // Lock memory
SharedData* data = static_cast<SharedData*>(sharedMemory.data());
data->statusCode = 200;
data->someValue = 42.0f;
strcpy(data->log, "Running OK");
sharedMemory.unlock();
semaphore.release();
👁️ Reading from Shared Memory (Qt UI)
Periodically read from a timer, e.g., every 1s:
semaphore.acquire(); // Lock semaphore
sharedMemory.lock(); // Lock memory
SharedData* data = static_cast<SharedData*>(sharedMemory.constData());
int status = data->statusCode;
float value = data->someValue;
QString logText = QString::fromUtf8(data->log);
sharedMemory.unlock();
semaphore.release();
🛑 Cleanup
Detach when done:
sharedMemory.detach();
🔐 Synchronization Flow
| Step | Action |
|---|---|
| 1 | Acquire QSystemSemaphore (blocks others) |
| 2 | Lock shared memory (sharedMemory.lock()) |
| 3 | Read or write data |
| 4 | Unlock shared memory |
| 5 | Release QSystemSemaphore |
🛡️ Key Best Practices
✅ Always lock memory after acquiring a semaphore
✅ Only one process creates shared memory (Qt UI)
✅ Others should only attach()
✅ Use detach() on exit
✅ Wrap read/write in try/catch if stability is critical
No comments:
Post a Comment