美文网首页程序员
Dispatch_Semaphore-持有计数的信号

Dispatch_Semaphore-持有计数的信号

作者: 文艺女青年的男人 | 来源:发表于2018-07-30 11:42 被阅读0次

    通常遇到多个线程访问同一块内存空间,我们会用同步队列处理(Serial Dispatch Queue)或者在异步队列中根据栅栏函数(dispatch_barrier_async)来避免数据竞争。

    但是当我们用栅栏函数的时候,会发现用这两种方法,执行的效率并不高,并不能完全体现出多线程的有点,所以如果考虑到更细粒度的排他控制,我们可以用Dispatch_Semaphore来操作。

    1.应用函数dispatch_semaphore_create来进行创建:

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

    2.等待函数:dispatch_semaphore_wait

    //第二个函数是dispatch_time_t 类型的时间,这里是永久等待

     long result = dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

     //可以安全的执行排他控制的处理

        if(result ==0) {

            //由于dispatch_semaphore 的计数值大于等于1

            //或者在待机中的指定时间

            //dispatch_semaphore的计数值减去1

            //执行需要进行排他控制的处理

        }else{

            //dispatch_semaphore 计数值为 0

            //达到指定时间为止待机

        }

    3.信号的引用计数加1函数:dispatch_semaphore_signal

    dispatch_semaphore_signal(semaphore);

    举一个例子:

    当我们创建了一个NSMutableArray,想要用多线程往数组里添加不同的数值,假设是1000组数据(显然这里不可能开1000个线程,我们现在只是考虑粒度的问题,暂不考虑开多少线程的问题),并且如果使用了多线程,那么肯定是需要添加防止数据竞争的操作来防止内存的错误,现在用更细粒度的排他控制来添加。

    上代码:

        //所以源代码中使用dispatch_semaphore

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

        //生成dispatch_semaphore,并且默认值计数值为1

        dispatch_semaphore_t semaphore1 = dispatch_semaphore_create(1);

        NSMutableArray *array = [[NSMutableArray alloc] init];

        for(inti =0; i <1000; i ++ ) {

            dispatch_async(queue, ^{

                //等待dispatch_semaphore 直到计数值大于或者等于1.

                dispatch_semaphore_wait(semaphore1, DISPATCH_TIME_FOREVER);

                //1.由于dispatch_semaphore 计数值 >= 1

                //2.所以将计数值减去1,并且dispatch_semaphore_wait执行回掉

                //3.计数值为“0”。

                //4.由于访问NSMutableArray 类对象的线程只有1个,因此可以安全的访问内存空间

                [arrayaddObject:[NSNumber numberWithInt:i]];

                //1.排他控制结束,需要对dispatch_semaphore计数进行加1

                //2.通过dispatch_semaphore_wait函数等待dispatch_semaphore的计数值增加的线程,有最先等待的线程执行。

                dispatch_semaphore_signal(semaphore1);

            });

        }

    相关文章

      网友评论

        本文标题:Dispatch_Semaphore-持有计数的信号

        本文链接:https://www.haomeiwen.com/subject/iwnxvftx.html