在之前的一篇文章中,我們講過了QSemaphore類,其可以用於同步多線程。而今天要講到的這個類,根據名字就可以猜測到,其可以在整個系統中使用,即它既可以用於多線程,也可以用於多線程。當然,這也意味着,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平臺上不存在應用程序崩潰後,信號量還存在的情況。
下面,我們寫兩個應用程序來使用一下系統級的信號量。
新建兩個Qt控制檯程序SystemSem1和SystemSem2,代碼如下:
SystemSem1:
#include <QCoreApplication>
#include <QSystemSemaphore>
#include <QDebug>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSystemSemaphore sem("sem", 1, QSystemSemaphore::Create);
while(true)
{
sem.acquire();
qDebug() << QCoreApplication::applicationPid();
QThread::sleep(1);
sem.release();
}
return a.exec();
}
SystemSem2:
#include <QCoreApplication>
#include <QSystemSemaphore>
#include <QDebug>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSystemSemaphore sem("sem", 1, QSystemSemaphore::Open);
while(true)
{
sem.acquire();
qDebug() << QCoreApplication::applicationPid();
QThread::sleep(1);
sem.release();
}
return a.exec();
}
我們在SystemSem1中創建信號量,在SystemSem2中打開信號量。
啓動這兩個程序,可以看到,每隔1秒,兩個程序會交替輸出各自的進程ID。