Qt5 C++下实现非对称互斥:允许并行创建数据,阻止创建与修改并发
解决方案
你的需求对应经典的读者-写者问题:允许多个"读者"(数据创建操作)并行执行,"写者"(全量数据修改操作)需要独占访问,且读写互斥。以下是基于Qt5的两种场景实现方案:
场景1:多线程环境(若你误将"线程"写为"进程")
Qt内置的QReadWriteLock完美匹配需求:读锁支持多线程共享持有(对应创建操作),写锁独占(对应修改操作),自动实现读写互斥、写写互斥。
代码示例
// 全局或类成员的读写锁,确保所有线程/函数可见 QReadWriteLock dataSyncLock; // 数据创建线程函数 void createData() { QReadLocker locker(&dataSyncLock); // 申请读锁,多线程可同时获取 // 执行独立数据创建逻辑(例如生成新数据对象并存储) // ... } // 全量数据修改函数 void modifyAllData() { QWriteLocker locker(&dataSyncLock); // 申请写锁,独占访问 // 遍历所有现有数据执行修改 // ... }
注意事项
- 禁止在持有读锁时尝试获取写锁,会触发死锁
- 若需从读操作升级为写操作,必须先释放读锁再申请写锁
- 可通过
dataSyncLock.setPreference(QReadWriteLock::PreferReader)调整锁的优先级,默认是写优先
场景2:真正的多进程环境
Qt没有提供原生跨进程读写锁,需基于进程间同步原语实现,或使用操作系统原生机制:
方案A:Qt原生组件模拟跨进程读写锁
用QSystemSemaphore控制访问权限,QAtomicInt记录活跃创建进程数(需放在共享内存中):
// 初始化跨进程共享的原子变量(借助QSharedMemory实现跨进程访问) QSharedMemory sharedMem("active_creators_shmem"); if (!sharedMem.create(sizeof(QAtomicInt))) { sharedMem.attach(); } QAtomicInt* activeCreators = static_cast<QAtomicInt*>(sharedMem.data()); if (sharedMem.isNewlyCreated()) { *activeCreators = 0; } // 跨进程信号量:控制修改操作(初始1,独占) QSystemSemaphore modifySem("data_modify_sem", 1, QSystemSemaphore::OpenOrCreate); // 跨进程信号量:控制创建操作(初始值设为足够大,比如1000) QSystemSemaphore createSem("data_create_sem", 1000, QSystemSemaphore::OpenOrCreate); // 数据创建进程逻辑 void createDataProcess() { createSem.acquire(); activeCreators->fetchAndAddOrdered(1); createSem.release(); // 执行数据创建 // ... activeCreators->fetchAndSubOrdered(1); } // 全量数据修改进程逻辑 void modifyAllDataProcess() { modifySem.acquire(); // 阻塞所有新创建操作 createSem.acquire(1000); // 等待所有正在进行的创建完成 while (activeCreators->loadAcquire() > 0) { QThread::msleep(10); } // 执行全量修改 // ... createSem.release(1000); modifySem.release(); }
方案B:操作系统原生跨进程锁
- Linux/macOS:使用
pthread_rwlock_t,初始化时设置PTHREAD_PROCESS_SHARED属性,将锁放在QSharedMemory实现跨进程访问 - Windows:由于SRWLOCK不支持跨进程,可通过
CreateMutex+CreateSemaphore组合模拟读写锁
对应设计模式
你的需求是读者-写者模式的典型应用,核心是区分共享访问(创建)和独占访问(修改)的权限控制。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

