QT: QSharedMemory создает несколько сегментов с одним и тем же ключом

Я пишу приложение для учебных целей, состоящее из двух исполняемых файлов. Среди прочего, каждый исполняемый файл создает свой собственный сегмент общей памяти (с разными ключами), после чего исполняемый файл A пытается создать сегмент, используя ключ B, а B делает то же самое с ключом A (цель этого для каждого исполняемого файла). чтобы проверить, работает ли еще один. Я знаю, что это, вероятно, не лучший способ добиться этого, но я прошу вас не заострять внимание на этом факте). Если одной из программ удается создать сегмент с ключом другой программы, она предполагает, что другая программа не запущена, и предпринимает соответствующие действия.

Проблема заключается в том, что это работает нормально, когда B проверяет A. Но когда A проверяет B, он может создать сегмент с тем же ключом, который уже создал B. Я почти уверен, что проверил все возможные условия гонки, и я также уверен, что оба сегмента существуют одновременно с одним и тем же ключом (оба вызова QSharedMemory создают вызовы с этим ключом, возвращая true). На самом деле, просто для смеха, я поместил вызов создания внутри цикла, и он может продолжать создавать сегмент с одним и тем же ключом до тех пор, пока цикл продолжается. Я попытался передать ключ непосредственно в конструкторе, используя setKey() и setNativeKey(), и ничего не сработало.

И, как было сказано ранее, меня действительно смущает то, что тот же подход работает для B, проверяющего A, но не наоборот.

Я не знаю, почему это происходит? Должен ли ключ соответствовать каким-либо стандартам? Есть ли у QSharedMemory ограничение или особое поведение при использовании внутри потока/сигнала/метода?

Фрагмент кода А (метод вызывается по сигналам - НЕ РАБОТАЕТ):

//Process A "signature" creation
QSharedMemory process_a_signature("61BB200D-3579-453e-9044-");
if(process_a_signature.create(512,QSharedMemory::ReadWrite)==true) {
    qDebug() << "Process A signature created.";
} else exit(0);

...

//Method that checks for process B (monitor)
void LaRunTime::checkMonitorProcess(){


QSharedMemory monitorsignature("61BB201D-3569-453e-9144-");
if(monitorsignature.create(512,QSharedMemory::ReadWrite)==true) {
    qDebug() << "Process B is not running.";
} else {
    qDebug() << "Process B is running.";
}

Фрагмент кода B (метод также называется с использованием сигналов - РАБОТАЕТ)

//Process B "signature" creation
QSharedMemory monitorsignature("61BB201D-3569-453e-9144-");
if(monitorsignature.create(512,QSharedMemory::ReadWrite)==true) {
    qDebug() << "Process B signature created.";
} else {
    exit(0);
}

...

//Method that checks for process A
void LaClientMonitor::checkProcess(){

QSharedMemory process_a_signature("61BB200D-3579-453e-9044-");
if(process_a_signature.create(512,QSharedMemory::ReadWrite)==true) {
    qDebug() << "Process A is not running.";
} else {
    qDebug() << "Process A is running.";
}

person Luis Carlos Jersak    schedule 20.12.2015    source источник
comment
Является ли целью определить во время запуска, нужно ли выполнить некоторую инициализацию (поскольку другой процесс этого не сделал), или целью является уведомление во время выполнения, если другой процесс перестает работать?   -  person John Zwinck    schedule 20.12.2015
comment
Цель состоит в том, чтобы уведомить во время выполнения, если другой процесс перестает работать.   -  person Luis Carlos Jersak    schedule 20.12.2015
comment
Не могли бы вы использовать для этого простое TCP-соединение между ними? Я думаю, что это проще и надежнее.   -  person John Zwinck    schedule 20.12.2015
comment
На самом деле да, но с UDP-подключением. Он оказался ненадежным по какой-то причине. Как вы думаете, TCP-соединение было бы лучше? Кроме того, я спросил здесь больше потому, что мне интересно, что происходит, чем из-за самой проблемы.   -  person Luis Carlos Jersak    schedule 20.12.2015
comment
UDP не имеет соединений. Вы должны использовать TCP с включенной поддержкой активности.   -  person John Zwinck    schedule 21.12.2015


Ответы (1)


Итак, поработав с кодом в нескольких других случаях, я обнаружил, что проблема возникает из-за того, что я создавал сегмент разделяемой памяти внутри класса/объекта и по какой-то причине (я полагаю, связанной с жизненным циклом объекта) он был уничтожен сразу после его создания. Перемещение кода, создающего сегмент памяти, в файл main.cpp решило проблему.

person Luis Carlos Jersak    schedule 02.01.2016