使用
- 创建 QSharedMemory 对象
- 调用 create 成员函数分配共享内存,或者 attach 附加到已创建的共享内存
- 使用内存 (注意lock、unlock)
#include <QtCore/QCoreApplication> #include <QtCore/QSharedMemory> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSharedMemory sharedmem("dbzhang800-shared-qt4"); if (sharedmem.create(1024)) { qDebug("shared memory created."); sharedmem.lock(); char * to = static_cast<char*>(sharedmem.data()); const char * from = "from dbzhang800-shared."; ::memcpy(to, from, 24); sharedmem.unlock(); } else if (sharedmem.attach()) { qDebug("shared memory attached."); sharedmem.lock(); const char * data = static_cast<const char*>(sharedmem.constData()); qDebug(data); sharedmem.unlock(); } else { qDebug("error."); } return a.exec(); }
Qt源码
源码组织方式
源码位于 src/corelib/kernel/
题外:正是看到这儿,才突然发现 QextSerialPort 源码组织的问题出在了那儿,因为当写 /*! */ 注释块时,发现竟没有合适的地方。
qsharedmemory.h | 头文件 |
qsharedmemory_p.h | 私有头文件 |
qsharedmemory.cpp | 类的实现,生成Qt文档的注释块在该文件中 |
qsharedmemory_win.cpp | 类中win相关的实现 |
qsharedmemory_unix.cpp | 类中unix相关的实现 |
qsharedmemory_symbian.cpp | 类中symbian相关的实现 |
windows部分的实现
简单看一下windows下实现,主要是 QSharedMemoryPrivate 类的几个函数
QSharedMemoryPrivate::create | 调用win api函数 CreateFileMapping |
QSharedMemoryPrivate::attach | 调用win api函数 MapViewOfFile,使用下面handle返回的句柄 |
QSharedMemoryPrivate::detach | 调用win api函数 UnmapViewOfFile |
QSharedMemoryPrivate::handle | 如果尚未未打开句柄,则调用win api函数 OpenFileMapping |
QSharedMemoryPrivate::cleanHandle | 调用win api函数 CloseHandle |
注意和 QSharedMemory api 中的对应关系:
QSharedMemory::create | 调用 d->create, 成功还调用 d->attach |
QSharedMemory::attach | d->attach |
QSharedMemory::detach | d->detach |
lock、unlock
- 这个功能是的实现需要跨进程的 互斥量或信号量来实现,这就是 QSystemSemaphore
- QSystemSemaphore 是Qt4.4 和QSharedMemory 引入的
QSyetemSemqphore 使用练习
#include <QtCore/QCoreApplication> #include <QtCore/QSystemSemaphore> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSystemSemaphore sem("dbzhang800-syssemphore", 1); sem.acquire(); qDebug("ok, system semaphore acquired"); qDebug("you can try run another instance. ^_^"); getchar(); sem.release(); return 0; }