天天看點

dispatch_semaphore信号量鎖的

dispatch_semaphore信号量是GCD用來同步的一種方式。

信号量通常用在 允許幾個線程同時通路一個資源,通過信号量來控制通路的線程個數.

與他相關的共有三個函數,分别是

dispatch_semaphore_create,dispatch_semaphore_signal,dispatch_semaphore_wait。

(1)dispatch_semaphore_create的聲明為:

  dispatch_semaphore_t   dispatch_semaphore_create(long value);

        其中value為信号量的初值,如果小于0則會傳回NULL ,傳回dispatch_semaphore_t類型的信号量。

(2)dispatch_semaphore_signal的聲明為:

  long  dispatch_semaphore_signal(dispatch_semaphore_t dsema)

  提高信号量,使傳入的信号量的值加1;

     傳回值為long類型,

     當傳回值為0時,表示目前 已經沒有線程等待其處理 (的信号量)

      當傳回值不為0時,表示其目前 有(一個或多個)線程等待其處理(的信号量),并喚醒一 個等待的線程

     注:(當線程有優先級時,喚醒優先級最高的線程;否則随機喚醒,線程一級一級的喚醒,直到傳回0)

 (3) dispatch_semaphore_wait的聲明為:

  long  dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

  等待降低信号量,使傳入的信号量的值減1;

      傳回值為long類型,

      當傳回值為0時 表示在timeout(時間長度)之前,該函數所處的線程被成功喚醒。

  當其傳回不為0時,表示阻塞線程 timeout時間。

  函數的作用: 如果信号量的值大于0,該線程就繼續執行下面的語句

                   如果信号量的值為0,那麼阻塞目前線程 等待timeout(時間長度)

                     (注意timeout的類型為dispatch_time_t,不能直接傳入整形或float型數)。

      注:在設定timeout時,比較有用的兩個宏:DISPATCH_TIME_NOW 和 DISPATCH_TIME_FOREVER。

  DISPATCH_TIME_NOW  表示目前;

  DISPATCH_TIME_FOREVER  表示遙遠的未來;

舉例分析

<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           

繼續閱讀