创建初始值为0的信号量会导致执行问题

时间:2016-05-11 06:40:43

标签: swift grand-central-dispatch semaphore

我正在学习GCD并且对信号量有疑问。 这是我的代码:

class ViewController: UIViewController {

    var semaphore: dispatch_semaphore_t! = nil

  override func viewDidLoad() {
    super.viewDidLoad()

    semaphore = dispatch_semaphore_create(0)


    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
      print("Entering")

      self.semaphoreTask()
      print(self.semaphore.debugDescription)
    }

    semaphoreTask()
     print(semaphore.debugDescription)
  }


  func semaphoreTask() {
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
    for i in 0...1000 {
      print(i)
      if i == 1000 {
        print("i is equal to 10000!")
      }
    }
    dispatch_semaphore_signal(self.semaphore)
  }

如果我运行此代码,那么semaphoreTask中没有任何内容在控制台中打印,但如果我更改

semaphore = dispatch_semaphore_create(0)

semaphore = dispatch_semaphore_create(1)

一切都开始运作良好。

问题是我为什么要写dispatch_semaphore_create(1)而不是0?

谢谢!

2 个答案:

答案 0 :(得分:6)

您可以通过两种不同的方式使用信号量:

  1. 说工作或资源准备好了。 在这种情况下,您将信号量设置为0.当某些内容准备就绪时,创建者会调用signal。消费者呼叫wait等待预期的项目/资源。
  2. 限制并发操作/请求/使用的数量。 在这种情况下,您以正值启动信号量,例如4.用户每次调用wait,如果资源可用,则允许他们继续。如果不是,他们被阻止。每个人完成资源后,他们会调用signal
  3. 那么,你看到它的预期是因为你将信号量设置为就绪标志,但是将其用作访问限制(因为你先调用wait)。

答案 1 :(得分:0)

所以我更正了我的代码,告诉你我是如何修复它的(感谢@Wain)。

class ViewController: UIViewController {

    var semaphore: dispatch_semaphore_t! = nil

  override func viewDidLoad() {
    super.viewDidLoad()

    semaphore = dispatch_semaphore_create(0)


    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
      print("Entering")

      self.semaphoreTask()
    }


    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
    semaphoreTask()
  }


  func semaphoreTask() {

    print(semaphore.debugDescription)
    for i in 0...1000 {
      print(i)
      if i == 1000 {
        print("i is equal to 10000!")
      }
    }
    dispatch_semaphore_signal(self.semaphore)
  }
}