程序员iOS DeveloperiOS Development

GCD之semaphore函数

2016-09-17  本文已影响76人  隔壁小鱼

GCD中, 有一些函数很常用, 比如同步函数, 异步函数, 障碍函数, 一次性函数等; 另外一些不太常用, 如迭代函数(dispatch_apply), 还有就是今天要说的信号量函数.

今天不打算介绍其他函数, 只说信号量函数.
<br />

以一个停车场的运作为例:
简单起见,假设停车场只有三个车位,一开始三个车位都是空的。
这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

从这段描述我们可以看出, 信号量的作用和互斥锁差不多, 都是保证线程安全的手段.

<br />

在GCD中, 有三个函数是semaphore的操作,

分别是:

  • dispatch_semaphore_create()
    作用: 创建一个semaphore函数, 并设置信号量总数.
    参数: 需要传入一个long int的参数, 这个参数就是信号量总数.
    返回值: 返回一个dispatch_semaphore_t类型的信号量对象.

从这段描述我们可以看出, 信号量函数有点类似于障碍函数, 两者都是阻塞型函数.

<br />

示例代码:

//创建一个信号量为0的semaphore函数. 因为要在block里用这个函数, 记得前面要加上__block.
__block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

//创建一个并发队列
 dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL);

//异步执行
dispatch_async(queue, ^(void) 
{        
         for (int i = 0; i < 5; i ++)
         {            
            NSLog(@">> i: %d", i);       
         }  
    dispatch_semaphore_signal(semaphore);   
 });

//虽然是并发队列+异步函数, 但执行到wait的时候, 发现信号量为0, 所以会阻塞在这里. 直到异步函数里的for循环执行完毕, 然后dispatch_semaphore_signal(semaphore)函数将信号量+1, 才会执行wait后面的for循环.
 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        for (int j = 0; j < 5; j ++) 
        {
            NSLog(@">> Main Data: %d", j);
        }

运行结果:

test[15518:632061] >> i: 0
test[15518:632061] >> i: 1
test[15518:632061] >> i: 2
test[15518:632061] >> i: 3
test[15518:632061] >> i: 4
test[15518:632036] >> Main Data: 0
test[15518:632036] >> Main Data: 1
test[15518:632036] >> Main Data: 2
test[15518:632036] >> Main Data: 3
test[15518:632036] >> Main Data: 4

上一篇 下一篇

猜你喜欢

热点阅读