信号量的总数代表的是可用资源的数量,不是有多少个线程在使用资源。
信号量的总数为0时表示可用资源为0。这时无可用资源给任务,需等待到有资源可用才可以执行任务。
示例代码:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(5);
for (int i = 0; i < 10000; i++) {
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//临界区,即待加锁的代码区域
dispatch_semaphore_signal(semaphore);
});
}
在GCD中有三个函数是semaphore的操作,分别是:
dispatch_semaphore_create
创建一个semaphore,参数指明信号的总量。
也就是可用资源的数量,从线程来说就是可以有多少个线程可以同时运行。
dispatch_semaphore_wait
如果此时信号总量等于0则一直等待, 直到信号总量>0,开始执行,并让信号总量-1。
在临界区结束时调用dispatch_semaphore_signal,表明不再使用资源了,释放一个资源。
dispatch_semaphore_signal发送一个信号,让信号总量加1。
可以这么理解:
1、比如一个理发店,有5名理发师,可以同时为5名客人理发。
就相当于 dispatch_semaphore_create(5);
2、来了一位客人理发,
相当于代码执行到了dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
想要进入dispatch_semaphore_wait下面临界区执行代码。
3、如果此时所有的理发师都在工作,则可用的理发师数量为0,则A客户等待。
相当于信号量的总数为0,任务等待进入dispatch_semaphore_wait下面的临界代码区。
4、等到有空着的理发师时,A客户不在等待,开始理发,此时空着的理发师数量减1。
相当于当信号量的总数大于0时,dispatch_semaphore_wait下面的代码开始执行,信号量的总数减1。
5、A客户理完发离开,可用的理发师增加1。
相当于执行到临界区底部的dispatch_semaphore_signal ,信号量加1。