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

Posted

技术标签:

【中文标题】带有 QSharedMemory 的 IPC 和如果进程之一挂起的风险【英文标题】:IPC with QSharedMemory and risk if one of process hang 【发布时间】:2017-08-24 06:21:36 【问题描述】:

我注意到如果某个进程挂起,QSharedmemory.Lock() 将永远持续。

而QT并没有提供像TryLock()这样的方法,所以如果一个childProcess死了,就会导致主进程出现问题,有什么解决方法吗?

【问题讨论】:

标记语言时请小心。 Qt 与 C 绝对没有任何关系。谢谢 :) (另外,添加一些代码,最好是 minimal reproducible example,说明你在问什么) 请您注意我的回答是否有任何帮助?如果没有,您能否提供帮助找到解决方案所需的详细信息? 感谢您的回复!对不起,我刚回到这个网站 【参考方案1】:

您可以将所有使用的 QSharedMemory.lock()/unlock() 调用包装在一个包装器对象中,无论返回路径是什么(抛出异常......),它都会确保共享内存的解锁。

例如:

class SharedMemoryLocker 
public:
    SharedMemoryLocker(QSharedMemory & sharedMemory):m_sharedMemoryWrapped(sharedMemory)  m_sharedMemoryWrapped.lock(); 
    ~SharedMemoryLocker()  m_sharedMemoryWrapped.unlock(); 

private:
    QSharedMemory & m_sharedMemoryWrapped;
;

一个使用示例是:

void f(QSharedMemory & mem) 
    
        SharedMemoryLocker locker(mem);
        // in this scope the shared memory is locked while no exception, return .. process ends
        // exiting will unlock the shared memory
     // QSharedMemoryLocker destructor is called here unlocking the shared memory
    // here the shared memory is unlocked

希望对你有帮助

【讨论】:

不喜欢给类命名为“QSharedMemoryLocker”,这有点暗示它是 Qt 提供的类,而不是用户提供的包装类。不过,RAII [资源获取是初始化] 的另一个重要用途。 你说得对,这只是作为示例代码的想法。已编辑!谢谢 “如果其中一个进程挂起”并不意味着该进程退出。进程退出时是否释放 RAII 资源。挂起!= 退出。 确实,这个问题可能应该细化,因为后来他谈到“a childProcess is dead”,我的回答与此有关。如果一个进程挂起,则意味着存在锁(死锁?)或其他问题,与开发/设计问题更相关。在大多数情况下,诸如我描述的模式之类的 RAII 可用于避免死锁。如果目的与某个进程挂起有关,则需要代码示例进行调查。

以上是关于带有 QSharedMemory 的 IPC 和如果进程之一挂起的风险的主要内容,如果未能解决你的问题,请参考以下文章

QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

跨两个不同进程的 QSharedMemory

Qt进程间通信之QSharedMemory示例

Qt进程间通信之QSharedMemory示例

Qt QSharedMemory 和 QDataStream

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