dispatch_semaphore搬运源码
之前这篇文章扒了扒libdispatch源码搬运了一些libdispatch的async和sync向关的方法,后来又看了看semaphore相关的,因为东西不多,逻辑也相对简单一些,所以只靠注释差不多就能解释清楚了。
dispatch_semaphore_t的结构
|
|
这里面 dsema_value 是用来表示资源数的值,当然对它的增减也都是原子操作。dispatch_semaphore_t 是 dispatch_semaphore_s 的指针表示。
dispatch_semaphore_create
|
|
可以看到,创建 dispatch_semaphore_t 对象的时候资源数不能小于0。
do_targetq 还没看见在哪里有什么用,其中 QOS 是 quality of service 的缩写。
dispatch_semaphore_signal
|
|
就是对 dsema_value 加1:
- 如果加1后大于0,那么增加资源成功;
- 如果加1后小于等于0,说明有地方调用了 wait 方法同步等待资源,那就需要调用 sem_post 将等待的线程唤醒。
dispatch_semaphore_wait
|
|
dispatch_semaphore_wait 一进入首先对 dsema_value 减1,如果减后大于等于0,那么获取资源成功。如果获取资源失败,那么进入下面的流程处理:
自定义超时时长
自定义超时时间的话,就在while循环中一遍遍去取尝试就好了,直到超时,如果在限时内获取到了资源,那就return了。如果获取资源等待超时,那么就进入 立刻获取资源 的case中,做最后一次尝试。
立刻获取资源
如果是立刻获取资源,就看一下 dsema_value 是不是>=0,如果是,那么表示资源获取成功了。否则的话说明资源获取失败,同时退出等待返回超时,因为一开始对资源进行了减1,所以这时要再对重新资源加1,表示不在等待。
一直等待资源
最后一种case,就是 DISPATCH_TIME_FOREVER 一直等待,就在while循环中一直调用 sem_wait 等待就好。其中 sem_wait 对应的唤醒方法应该就是前面的 sem_post。由此可见 dsema_value 的值是有可能为负数的,说明当前有排队等待资源的情况。
对源码的翻译有误希望大家使劲拍。