QT:QSharedMemory 正在使用相同的键创建多个段

Posted

技术标签:

【中文标题】QT:QSharedMemory 正在使用相同的键创建多个段【英文标题】:QT: QSharedMemory is creating multiple segments with the same key 【发布时间】:2015-12-20 05:27:26 【问题描述】:

出于学习目的,我正在编写一个由两个可执行文件组成的应用程序。除其他外,每个可执行文件创建自己的共享内存段(使用不同的密钥),之后可执行文件 A 尝试使用 B 的密钥创建一个段,而 B 对 A 的密钥执行相同操作(这样做的目的是针对每个可执行文件检查另一个是否仍在运行。我知道这可能不是完成此任务的最佳方法,但我要求您不要专注于这个事实)。如果任一程序成功地使用对方的密钥创建了一个段,则假定对方没有运行并采取相应的措施。

发生的问题是,当 B 检查 A 时,这可以正常工作。但是当 A 检查 B 时,它可以使用 B 已经创建的相同密钥创建一个段。我很确定我检查了所有可能的竞争条件,而且我也很确定这两个段同时存在并具有相同的键(两个 QSharedMemory 使用此键创建调用都返回 true)。事实上,只是为了咯咯笑,我已经将 create 调用放在循环中,只要循环继续,它就可以使用相同的键继续创建段。我尝试直接在构造函数中传递密钥,使用 setKey() 并使用 setNativeKey() 并且没有工作。

如前所述,真正让我感到困惑的是,同样的方法适用于 B 检查 A,但反之则不行。

我不知道为什么会这样?密钥是否必须遵循任何标准? QSharedMemory 在线程/信号/方法中使用时是否有限制或特定行为?

A 的代码片段(使用信号调用方法 - 不起作用):

//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的代码sn-p(方法也叫使用信号-WORKS)

//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.";

【问题讨论】:

目的是在启动过程中识别是否需要进行一些初始化(因为其他进程还没有完成),还是在其他进程停止运行时在运行时得到通知? 目的是在运行时通知其他进程是否停止运行。 您会考虑在它们之间使用简单的 TCP 连接吗?我认为它更简单可靠。 实际上是的,但是使用 UDP 连接。由于某种原因,结果证明是不可靠的。你认为 TCP 连接会更好吗?另外,我在这里问更多是因为我对正在发生的事情感到好奇,而不是因为问题本身。 UDP 没有连接。您应该使用启用了 keep-alive 的 TCP。 【参考方案1】:

所以,在其他几个场合摆弄代码后,我发现问题正在发生,因为我在类/对象内创建共享内存段,并且出于某种原因(我相信与对象)它在创建后立即被销毁。 将创建内存段的代码移至 main.cpp 文件即可解决问题。

【讨论】:

以上是关于QT:QSharedMemory 正在使用相同的键创建多个段的主要内容,如果未能解决你的问题,请参考以下文章

Qt QSharedMemory 和 QDataStream

Qt进程间通信之QSharedMemory示例

Qt进程间通信之QSharedMemory示例

带有 QSharedMemory 的 IPC 和如果进程之一挂起的风险

如何关闭 Qt 子进程并让子进程执行清理代码?

使用 QSharedMemory 附加现有的共享内存