天天看点

Qt之进程间通信(共享内存)简述QSharedMemoryQSystemSemaphore注意事项加载进内存从内存中读取

上一节中,我们分享下如何利用windows消息机制来进行不同进程间的通信。但是有很多局限性,比如:不能跨平台,而且必须两个进程同时存在才可以,要么进程a发了消息谁接收呢?

下面我们来分享另外一种跨平台的进行间通信的方式-shared memory(共享内存)。

qt提供的基于共享内存的ipc有qsharedmemory类和qsystemsemaphore类,qsharedmemory可以访问共享内存区域,以及多线程和进程的共享内存区域。而qsystemsemaphore类用于访问系统共享资源,以实现独立进程间的通信。

<a href="#%e7%ae%80%e8%bf%b0">简述</a>

<a href="#qsharedmemory">qsharedmemory</a>

<a href="#qsystemsemaphore">qsystemsemaphore</a>

<a href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9">注意事项</a>

<a href="#%e5%8a%a0%e8%bd%bd%e8%bf%9b%e5%86%85%e5%ad%98">加载进内存</a>

<a href="#%e8%af%b4%e6%98%8e">说明</a>

<a href="#%e5%ae%9e%e7%8e%b0">实现</a>

<a href="#%e4%bb%8e%e5%86%85%e5%ad%98%e4%b8%ad%e8%af%bb%e5%8f%96">从内存中读取</a>

<a href="#%e8%af%b4%e6%98%8e-1">说明</a>

<a href="#%e5%ae%9e%e7%8e%b0-1">实现</a>

qsharedmemory读写内存时,可以使用lock()实现同步。因此,如果同步完成,必须使用unlock()为共享内存区域解锁。

qsharedmemory可以使用attach()访问共享内存。可以通过指定参数来设置共享内存的访问模式。如果使用的是qsharedmemory::readonly模式,则只能通过只读模式访问共享内存。反之,使用qsharedmemory::readwrite模式则可以通过读写模式访问共享内存。

qsharedmemory拥有进程并提供可以返回共享内存区域指针的成员函数。在共享内存区域,成员函数constdata()可以通过void类型返回进程正在使用的内存区域指针。创建共享时,qsharedmemory可以以字节为单位分配共享内存区域,还可以通过第二个参数设置函数attach()提供的模式。

qsharedmemory可以设置特定共享内存的固定键。函数setnativekey()可以设置共享内存对象的键,该函数使用从属平台的共享内存的键进行相关设置。相反,使用函数setkey()可以设置与独立与平台的键。函数setkey()创建与平台本地键(native key)映射的键。

qsystemsemaphore可以提供普通系统的信号量。信号量使用互斥体,而互斥体只可以使用1次锁定(block)。因此,qsemaphore类不能对有效资源使用多线程,而qsystemsemaphore类可以再多进程或多线程中实现。

qsystemsemaphore与qsemaphore类不同,可以访问多进程。这表示qsystemsemaphore是一个重量级的类。因此,使用单一线程或进程时,建议使用qsemaphore。获得资源前,成员函数acquire()始终阻塞。函数release()用于释放资源,且该函数可以设置参数。该函数的参数&gt;1时,释放资源。

初始化qsharedmemory时,必须指定一个唯一的标识key,进程的key必须保持一致。可以使用setkey来设置。

进程a-写

分为下面几步:

检测该进程是否连接到共享内存段,如果连接,则将该进程与共享内存段分离。

从系统足够大的内存中得到一个新的共享内存段。

锁定该共享内存段,以阻止第二个对话框进程访问,将缓冲区中的图片复制进共享内存段。

将共享内存段解锁,然后第二个对话框进程就可以访问了。

进程b-读

将该进程与进程a创建的共享内存段绑定

锁定共享内存段,复制数据到缓冲区,然后写入到qimage中。

将共享内存段解锁,然后将该进程与共享内存段分离。

继续阅读