您的位置:首页 > 移动开发 > IOS开发

iOS学习笔记74-完整详解GCD系列(四)dispatch_semaphore(信号量)

2016-04-26 16:57 585 查看
原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=contents
一 何为信号量?

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

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

二 如何使用信号量

三个主要函数

创建一个信号量

[plain] view
plain copy

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

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

提高信号量

[plain] view
plain copy

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

等待降低信号量

[plain] view
plain copy

func dispatch_semaphore_wait(_ dsema: dispatch_semaphore_t!,

_ timeout: dispatch_time_t) -> Int

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

三 举例分析

[plain] view
plain copy

<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时候

输出

[objc] view
plain copy

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的时候

[objc] view
plain copy

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的时候

[objc] view
plain copy

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: