QSemaphore 进程级信号量:
轻量级线程同步技术,用于同一进程内多线程之间的同步互斥。
QSystemSemaphore 系统级信号量:
可以在整个系统中使用,即它既可以用于多进程,也可以用于多线程。QSystemSemaphore类是一个比较重量级的线程同步互斥类。
所以,除非在同步多进程的情况下,否则不应该使用该类。其他方面,该类和QSemaphore均相同,操作也相同。
QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue = 0, AccessMode mode = Open)
QSemaphore相比,多了一个key,也可以理解为该信号量的名字,多个进程间就是通过这个名字来操作同一个信号量的。
另外还多了一个mode参数,该参数可以取两个值Open和Create。其中,**Open在请求的信号量已存在时,就使用它,并且不会重置信号的资源数,如果请求的信号量不存在,就 创建它并为它设置初始的资源值。**而对于Create来说,不管请求的信号量是否已存在,它都会取得信号量的拥有权,并设置初始值。所以,我们应该在第一次创建信号量时,为其传入Create参数。但在Windows平台上,Create和Open的行为相同,因为,Windows平台上不存在应用程序崩溃后,信号量还存在的情况。
在windows中如果信号量已经存在,再次使用create创建信号量时,创建出的信号量是之前已经存在的信号量,初始值并不会被重新设置。
//程序1:创建初始值为1的信号量
QSystemSemaphore* pSem = new QSystemSemaphore(QString::fromStdString("semaphoretest"), 1, QSystemSemaphore::Open);//(使用open若信号量已经存在则使用已存在的信号量,若信号量不存在则创建信号量并设置初始值为1)
if (pSem->acquire())
{
QMessageBox::critical(NULL, "", "");
}
pSem->release();
//程序2:创建初始值为1的信号量
QSystemSemaphore* pSem = new QSystemSemaphore(QString::fromStdString("semaphoretest"), 1, QSystemSemaphore::Create);//使用Create创建信号量,若信号量已经存在则使用已存在的信号量,若信号量不存在则创建信号量并设置初始值为1,在windows中create和open作用是一样的
if (pSem->acquire())//当程序1acquire时程序2在此处阻塞住,知道程序1执行了release,该程序才继续往下执行。
{
QMessageBox::critical(NULL, "", "");
}
pSem->release();
QSharedMemory创建共享内存:
使用QSharedMemory的create函数创建共享内存,当共享内存不存在时可以创建成功,并自动进行attach(所以此时再attach会返回false,此时使用isAttached会返回true)。当共享内存已经存在时,使用create函数会返回false,但不影响继续使用该共享内存(QSharedMemory)对象进行attach操作,此时即使创建create失败(因为共享内存已经存在),也不影响继续attach(因为共享内存已存在)。
//程序1:定义共享内存对象,并创建共享内存
QSharedMemory* pMem = new QSharedMemory(QString::fromStdString("sharememoryTest"));
if (pMem->isAttached())
{
pMem->detach();
}
bool bSuccess = pMem->create(1024);
if (pMem->isAttached())//当共享内存不存在创建成功时,该处会返回true
{
QMessageBox::critical(NULL, "", "attached");
}
if (pMem->attach())//由于已自动绑定(attach),此处再attach会返回false
{
QMessageBox::critical(NULL, "", "success");
}
else{
QSharedMemory::SharedMemoryError err = pMem->error();
err = pMem->error();
}
//程序2:创建初始值为1的信号量
QSharedMemory* pMem = new QSharedMemory(QString::fromStdString("sharememoryTest"));
if (pMem->isAttached())
{
pMem->detach();
}
bool bSuccess = pMem->create(1024);//先运行程序1,共享内存已存在,此处create会返回false
if (pMem->isAttached())
{
QMessageBox::critical(NULL, "", "attached");
}
if (pMem->attach())//即使上边创建返回false,此处依然可以绑定(返回true,因为共享内存在程序1中已经被创建,是存在的)
{
QMessageBox::critical(NULL, "", "success");
}
else{
QSharedMemory::SharedMemoryError err = pMem->error();
err = pMem->error();
}
当一个程序使用QSharedMemory的create创建共享内存成功后,此时另一程序去做同样操作,使用QSharedMemory的create去创建同名共享内存会创建失败;若程序一创建成功后,后边执行了detach操作,即使程序一没退出,此时程序2去创建同名共享内存可以创建成功,说明程序执行了QSharedMemory的Detach操作后就不再具有该共享内存的占有权,相当于已经释放该资源;当所有占用该共享内存的程序都执行了Detach操作则该共享内存会消失。
所以如果想使用QSharedMemory使多个程序共享一段共享内存,则需要至少一个程序拥有该共享内存的占有权,防止共享内存消失。