Monday, May 5, 2025

Shared Memory Usage Between Qt UI and Separate process

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

LeetCode C++ Cheat Sheet June

🎯 Core Patterns & Representative Questions 1. Arrays & Hashing Two Sum – hash map → O(n) Contains Duplicate , Product of A...