完整详解GCD系列(四)dispatch_semaphore(信号量)

原创Blog,转载请注明出处

http://blog.csdn.net/hello_hwc?viewmode=contents

一 何为信号量?

简单来说就是控制访问资源的数量,比如系统有两个资源可以被利用,同时有三个线程要访问,只能允许两个线程访问,第三个应当等待资源被释放后再访问。

注意:再GCD中,只有调度的线程在信号量不足的时候才会进入内核态进行线程阻塞

二 如何使用信号量

三个主要函数

创建一个信号量

func dispatch_semaphore_create(_ value: Int) ->  dispatch_semaphore_t !

其中value为信号量的初值,如果小于0则会返回NULL

提高信号量

func dispatch_semaphore_signal(_ dsema: dispatch_semaphore_t!) -> Int

等待降低信号量

func dispatch_semaphore_wait(_ dsema: dispatch_semaphore_t!,
                           _ timeout: dispatch_time_t) -> Int

注意,正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。

三 举例分析

<pre name="code" class="objc">//
//  ViewController.swift
//  SwiftTestExample
//
//  Created by huangwenchen on 15/1/6.
//  Copyright (c) 2015年 huangwenchen. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    var semaphore:dispatch_semaphore_t;
    required init(coder aDecoder: NSCoder) {
        self.semaphore = dispatch_semaphore_create(1)
        super.init(coder: aDecoder)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {() -> Void  in
             self.task_first()
        })
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { () -> Void in
            self.task_second()
        })
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { () -> Void in
            self.task_third()
        })
        // Do any additional setup after loading the view, typically from a nib.
    }
    func task_first(){
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
        NSLog("%@","First task starting")
        sleep(1)
        NSLog("%@", "First task is done")
        dispatch_semaphore_signal(self.semaphore)
    }
    func task_second(){
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
        NSLog("%@","Second task starting")
        sleep(1)
        NSLog("%@", "Second task is done")
        dispatch_semaphore_signal(self.semaphore)
    }
    func task_third(){
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
        NSLog("%@","Thrid task starting")
        sleep(1)
        NSLog("%@", "Thrid task is done")
        dispatch_semaphore_signal(self.semaphore)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

这段代码模拟提交三个任务,提交到全局队列(并行队列)

当信号量的初初始为2时候

输出

2015-01-06 19:42:01.963 SwiftTestExample[632:11631] First task starting
2015-01-06 19:42:01.964 SwiftTestExample[632:11630] Second task starting
2015-01-06 19:42:02.971 SwiftTestExample[632:11630] Second task is done
2015-01-06 19:42:02.971 SwiftTestExample[632:11631] First task is done
2015-01-06 19:42:02.971 SwiftTestExample[632:11633] Thrid task starting
2015-01-06 19:42:03.974 SwiftTestExample[632:11633] Thrid task is done

当信号量为3的时候

2015-01-06 19:42:49.912 SwiftTestExample[666:12259] First task starting
2015-01-06 19:42:49.912 SwiftTestExample[666:12258] Second task starting
2015-01-06 19:42:49.912 SwiftTestExample[666:12260] Thrid task starting
2015-01-06 19:42:50.915 SwiftTestExample[666:12259] First task is done
2015-01-06 19:42:50.915 SwiftTestExample[666:12260] Thrid task is done
2015-01-06 19:42:50.915 SwiftTestExample[666:12258] Second task is done

当信号量为1的时候

2015-01-06 19:43:35.140 SwiftTestExample[694:12768] First task starting
2015-01-06 19:43:36.145 SwiftTestExample[694:12768] First task is done
2015-01-06 19:43:36.145 SwiftTestExample[694:12771] Second task starting
2015-01-06 19:43:37.146 SwiftTestExample[694:12771] Second task is done
2015-01-06 19:43:37.146 SwiftTestExample[694:12769] Thrid task starting
2015-01-06 19:43:38.150 SwiftTestExample[694:12769] Thrid task is done
时间: 2024-12-25 01:24:14

完整详解GCD系列(四)dispatch_semaphore(信号量)的相关文章

完整详解GCD系列(一)dispatch_async;dispatch_sync;dispatch_

为什么要写这个系列,因为百度了一下,找了很多都是些片面的Blog,拷贝来拷贝去的,写的也很粗糙. 所以,我要写这个系列,尽量把官网文档中GCD的强大功能完整的表达出来.方便自己,也方便别人,如果发现有问题,欢迎提出 本教程的计划:在完整的看过GCD的官方文档之后,我实在想不出来如何用一篇文章详细完整的写出来如此多的功能.所以,决定开一个专栏来写这个教程.计划8篇文章,分别介绍各种功能,每种功能会附上简单完整的示例代码.最后 的一篇文章会进行总结,总结出GCD的经典使用场景.源代码只提供Swift

完整详解GCD系列(一)dispatch_async;dispatch_sync;dispatch_async_f;dispatch_sync_f

为什么要写这个系列,因为百度了一下,找了很多都是些片面的Blog,拷贝来拷贝去的,写的也很粗糙. 所以,我要写这个系列,尽量把官网文档中GCD的强大功能完整的表达出来.方便自己,也方便别人,如果发现有问题,欢迎提出 本教程的计划:在完整的看过GCD的官方文档之后,我实在想不出来如何用一篇文章详细完整的写出来如此多的功能. 所以,决定开一个专栏来写这个教程.计划8篇文章,分别介绍各种功能,每种功能会附上简单完整的示例代码.最后 的一篇文章会进行总结,总结出GCD的经典使用场景.源代码只提供Swif

完整详解GCD系列(三)-dispatch_group

原创Blog,转载请注明出处 http://blog.csdn.net/column/details/swift-gcd.html 一.dispatch_group 把一组任务提交到队列中,这些队列可以不相关,然后坚挺这组任务完成的事件. 几个用到的函数 1.dispatch_group_create创建一个调度任务组 func dispatch_group_create() -> dispatch_group_t! 2.dispatch_group_async 把一个任务异步提交到任务组里 f

完整详解GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

一.dispatch_after 功能:延迟一段时间把一项任务提交到队列中执行,返回之后就不能取消 常用来在在主队列上延迟执行一项任务 函数原型 [plain] view plaincopy func dispatch_after(_ when: dispatch_time_t, _ queue: dispatch_queue_t!, _ block: dispatch_block_t!) 参数 [plain] view plaincopy when 过了多久执行的时间间隔 queue   提交

「视频直播技术详解」系列之七:直播云 SDK 性能测试模型

?关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 本系列文章大纲如下: (一)采集 (二)处理 (三)编码和封装 (四)推流和传输 (五)延迟优化 (六)现代播放器原理 (七)SDK 性能测试模型 本篇是<视频直播技术详解>系列的最后一篇直播云 SDK 性能测试模型,SDK 的性能对最终 App 的影响非常大.SDK 版本迭代快速,每次发布前都要进行系统的测试,测试要

Spring4.0MVC学习资料,Controller中的方法详解和使用(四)

在以前,mvc的框架,基本上就是struts框架了.但是现在不一样了.springmvc出来了.spring的mvc框架不亚于struts了,springmvc出来了,我们有了更多的选择. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是 Struts 这样的 We

TCP/IP详解 笔记十四

TCP/IP协议(二)  连接的建立与终止 tcpdump -S输出TCP报文的格式 格式: 源>目的:标志 (标志就是tcp头部).标识首字符意义如下: 例如:telnet 某服务的输出(包括连接建立和终止) 标识解释:S 1415531521:1415531521(0) win 4096 <mss 1024> S(SYN):代表建立一个连接 1415531521:1415531521(0) :本次传送的首字节序号是1415531521(这里是ISN),尾字节序号是1415531521

「视频直播技术详解」系列之四:推流和传输

关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 在上一期中,我们介绍了讲解编码和封装. 本篇是<解密视频直播技术>系列之四:推流和传输.推流是直播的第一公里,直播的推流对这个直播链路影响非常大,如果推流的网络不稳定,无论我们如何做优化,观众的体验都会很糟糕.所以也是我们排查问题的第一步,如何系统地解决这类问题需要我们对相关理论有基础的认识. 本系列文章大纲如下: (一

详解listview的四种适配器模式

ListView是Android开发中比较常用的一个组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示.比如说我们手机里的通讯录就使用到了ListView显示联系人信息.ListView同时也是所有Android UI控件中最为麻烦的控件,之所以麻烦就是因为它的各种的适配器特别麻烦. 创建ListView有两种方式: 1.直接创建ListView 2.让Activity继承ListActivity 列表的显示需要三个元素: 1.ListVeiw :用来展示列表的View. 2.适