首先看一下QSharedMemory在不同平台下的差异问题
详细描述
QSharedMemory 类提供了对一段共享内存的访问。(译注:“一段共享内存”在后续译文中也译为“共享内存段”)
QSharedMemory 提供了被多线程和多进程共享的一段内存的访问。它也提供了方法,为单线程或单进程锁定内存以实现互斥访问。
当使用这个类的时候,要知道以下不同平台的差异:
- Windows: QSharedMemory并不“拥有”这段共享内存。当所有“拥有一个QSharedMemory的实例从而附着于某一段共享内存”的进程或线程销毁了它们的QSharedMemory实例或者退出了,Windows内核会自动释放这一段共享内存。
- Unix: QSharedM“拥有”这段共享内存。当最后一个拥有附着于某段共享内存的线程或进程通过销毁QSharedMemory实例从而与这段共享内存分离后,Unix内核会释放这段共享内存。但是如果最后这个线程或进程崩溃了而没有运行QSharedMemory的析构函数时,这段共享内存会逃过本次崩溃而没有被释放。
- HP-UX: 每个进程只有一个线程能够附着于(attach to)一段共享内存。这就是说,在HP-UX上,QSharedMemory不应该被同一个进程内的多线程使用。
在读写共享内存前,要用lock();而在使用完毕后,要用unlock()来结束锁定。
我在windows系统上使用QSharedMemory的时候没出现任何问题,当把工程移到Linux系统上时,出现了问题,由于我的工程是一个QCoreApplication程序,当程序异常退出时,QSharedMemory实例对象未析构导致共享内存会处于挂机状态,后面启动该程序会一直报共享内存已存在的错误。为了解决异常退出时出现的内存挂起状态。
使用如下方法可解决在linux系统下异常退出导致的问题。
在创建内存时调用
bool create(int size, AccessMode mode = ReadWrite)如果错误为QSharedMemory::AlreadyExists,表示共享内存已存在未被释放,则需要调用
先attach函数将进程附着到QSharedMemory上,再调用detach函数即可释放掉该异常导致的挂起共享内存,然后便可重新创建内存。