QSemaphore提供了一个通用的可计数的信号量。
信号量实际上就是广义的互斥量。一个互斥量只能被锁定一次,然而一个信号量可以被获取多次。信号量常被用于保护一定数目的同类资源。
信号量支持两种基本的操作:acquire()和 release()
acquire(n)尝试获取n个资源。如果没有这么多数目的资源可用,它就阻断调用它的程序直到资源可用。
release(n)释放n个资源tryAcquire()尝试获取资源,如果资源数目不够就立即返回。available()函数用于返回可用资源的数目。
例子:
QSemaphore sem(5); // sem.available() == 5
sem.acquire(3); // sem.available() == 2
sem.acquire(2); // sem.available() == 0
sem.release(5); // sem.available() == 5
sem.release(5); // sem.available() == 10
sem.tryAcquire(1); // sem.available() == 9, returns true
sem.tryAcquire(250); // sem.available() == 9, returns false
信号量的一个典型的应用就是用来控制环形缓冲区的读写,这个环形缓冲区被生产者和消费者共同访问。这个信号量的例子演示了如何应用信号量来解决该问题。
一个关于信号量的非计算机的问题就是餐厅问题。信号量的初始值为餐厅凳子总数目。当有客人到,他就需要凳子。当凳子被坐下,可用的凳子数就减少。当客人离开,可用的凳子数就增加,就允许更多的人进入。如果有10个人需要凳子,但是只有9张凳子,那么这10个人将等待。如果有4个人需要凳子,他们可以直接坐下(这样就只剩下5张凳子空着,那10个人将等得更久)。
请参考 QMutex, QWaitCondition, QThread, and Semaphores Example.
成员函数说明
QSemaphore::QSemaphore ( int n = 0 )
新建一个信号量,守护的资源数为n(默认为0)
请参考 release() and available().
QSemaphore::~QSemaphore ()
销毁信号量警告:销毁一个正在使用的信号量将导致一个不确定的行为。
void QSemaphore::acquire ( int n = 1 )
从该信号量守护的资源中获取n个资源。如果获取的资源数目大于available()返回值,那么该调用将阻塞,直到可获取足够的资源数。
请参考 release(), available(), and tryAcquire().
int QSemaphore::available () const
返回当前信号量可以使用的资源的数目。该数不能为负。
请参考 acquire() and release().
void QSemaphore::release ( int n = 1 )
释放n个信号量守护的资源给信号量。该函数也可以用来增加一个信号量可使用的资源数目,例如
QSemaphore sem(5); // a semaphore that guards 5 resources
sem.acquire(5); // acquire all 5 resources
sem.release(5); // release the 5 resources
sem.release(10); // "create" 10 new resources
请参考 acquire() and available().
bool QSemaphore::tryAcquire ( int n = 1 )
尝试从信号量守护的资源中获取n个资源。成功,则返回true。如果当前可用的资源数目不够立即返回,返回值为false,并且不占用任何资源。例如:
QSemaphore sem(5); // sem.available() == 5
sem.tryAcquire(250); // sem.available() == 5, returns false
sem.tryAcquire(3); // sem.available() == 2, returns true
请参考 acquire().
bool QSemaphore::tryAcquire ( int n, int timeout )
尝试从信号量守护的资源中获取n个资源。成功,则返回true。如果当前可用的资源数目available()不够,将等待timeout微秒。
注意:超时参数timeout为负数的话,就等同于调用acquire()函数。例如:
QSemaphore sem(5); // sem.available() == 5
sem.tryAcquire(250, 1000); // sem.available() == 5, waits 1000 milliseconds and returns false
sem.tryAcquire(3, 30000); // sem.available() == 2, returns true without waiting
请参考 acquire().