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

/-------------注意----------------

这篇文章是在Swift 1.0时代写的,已经不适合当前的语法。关于Swift最新版本的GCD,参见我的这篇博客

/-------------注意----------------



一 何为信号量?

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

注意:再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


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值