iOS梅开二度 - GCD之计数信号量(dispatch_semaphore_t)

栏目: IOS · 发布时间: 5年前

内容简介:文章必须有一个前言:在默默coding的时候,涉及到了一个点,就是某块代码的执行受到某一个变量的限制,如果当前变量为YES,则可以执行此块代码,但并不知道这个变量会在什么时候设置为YES;比较直接的思路就是监听变量值得变化,从而决定是否执行代码;不过还是想看看有没有更好(高大上)的方式,于是乎思虑万千,“等待”、“允许执行”、、、这几个词语轮回旋转,wait,对哦,信号量是个好东西,由此有了今天的一篇小知识点文章;注意,正文了:

文章必须有一个前言:

在默默coding的时候,涉及到了一个点,就是某块代码的执行受到某一个变量的限制,如果当前变量为YES,则可以执行此块代码,但并不知道这个变量会在什么时候设置为YES;比较直接的思路就是监听变量值得变化,从而决定是否执行代码;不过还是想看看有没有更好(高大上)的方式,于是乎思虑万千,“等待”、“允许执行”、、、这几个词语轮回旋转,wait,对哦,信号量是个好东西,由此有了今天的一篇小知识点文章;

注意,正文了:

信号量:多用于多线程中,在多线程开发的过程中不可避免的会涉及到并发的问题,尤其是在我们并不想让某些关键代码被并发执行的时候,可以使用信号量来解决;在描述到这个话题的时候,不可避免的会想到@synchronized 同步锁,在某些情况下同步锁也能解决我们多线程共同访问关键代码的问题。

自我的理解看来(代码一和代码二都会触发关键代码)

1.同步锁:代码一和代码二都回去敲一下关键代码的门,而后在门口进行等待,等待被允许进入;信号量:代码一和代码二都在各自的家中等着通知,当被通知可以进行访问的时候,代码一和代码二将会从家出发去关键代码,并且直接进门

2.通过第一点的描述也可以看出另外一个问题,同步锁不会执行顺序的规则,来者不拒;而信号量绘指定一个顺序也就是需要先排好队(考虑这个问题,请忽略信号量可以限制多个资源共同访问的现象)

3.通过第二点衍生出这个问题,信号量是可以制定访问规则为多个资源功能访问;而同步锁就比较尴尬了,只能One by One,前者不出来,后者就是进不去。(是不是屋子太小了,容不下两个人,哈哈)

实际场景:代码一和代码二都需要触发关键代码来进行后续操作,那么代码一和代码二都需要去获取信号量,当代码一被允许执行的时候,会成功调用关键代码,且在关键代码调用成功的时候会释放信号量,当代码二接收到信号量被释放的信号,这意味着代码二就可以进入执行了。

小二,上一个变量给我,速度的:

// 计数信号量
    dispatch_semaphore_t semaphore;

再给我来点解饿的,要硬菜,特别硬:(创建一个计数值为0的信号量)

if (!semaphore) {
        /*!
         * Apple Documentation : dispatch_semaphore_t dispatch_semaphore_create(long value);
         *
         * 创建具有初始值的新计数信号量 : 在这里我们设置为0,这意味着信号量创建之后将意味着dispatch_semaphore_wait之后的代码不可执行(wait在后续介绍)
         *
         * 要点1 : 当两个线程需要协调特定事件的完成时,为值传递零是有用的
         * 要点2 : 传递大于零的值对于管理有限的资源池非常有用,其中池大小等于该值
         *
         * 注意  : 信号量的起始值传递小于零的值将导致返回NULL
         */
        semaphore = dispatch_semaphore_create(0);
    }

什么?我的硬菜还得等会?那什么时候能好,行吧,那我等会吧(使用信号量的话,每一个执行点都需要调用wait函数等待,等待被唤醒)

//创建异步执行的环境(Apple Documentation : 提交一个用于在调度队列上进行异步执行的代码块)
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        /*!
         * semaphore - 等待(减少)信号量
         *
         * @param semaphore
         * @param DISPATCH_TIME_FOREVER 永远等待
         *
         * 返回值:
         * 1. 如果结果值小于零,则此函数在返回之前等待信号发生
         * 2. 如果结果值非零,则线程被唤醒
         */
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        //处理被唤醒的代码
        
        
        //返回主线程处理UI
        dispatch_async(dispatch_get_main_queue(), ^{
            //show the view
        });
    });

等待了N久,已经饿得不行了,通过观察得知,硬菜已经做好了,但是小二在刷盘子没空上菜,不过,哼哼。俗话说技多不压身,通过学习的代码技能,调整一下小二的工作,于是写下了如下代码,然后小二就立即把菜端了上来。可以吃了。

/*!
     * semaphore +1 : broken the forever waiting
     * 增加计数信号量。如果前一个值小于零,则此函数在返回之前唤醒等待的线程。写在wait后面的代码(dispatch_semaphore_wait)
     */
    dispatch_semaphore_signal(semaphore);

到这里就结束了,想看更多精彩内容吗,呵呵,没有了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Parsing Techniques

Parsing Techniques

Dick Grune、Ceriel J.H. Jacobs / Springer / 2010-2-12 / USD 109.00

This second edition of Grune and Jacobs' brilliant work presents new developments and discoveries that have been made in the field. Parsing, also referred to as syntax analysis, has been and continues......一起来看看 《Parsing Techniques》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具