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

Creating semaphore with initial value of 0 make issues with execution

我正在学习 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?

谢谢!

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

  1. 表示工作或资源何时准备就绪。 在这种情况下,您从 0 开始信号量。创建者在准备就绪时调用 signal。消费者调用 wait 等待预期的项目/资源。
  2. 限制并发操作/请求/使用的数量。 在这种情况下,您以正值启动信号量,例如 4。每个用户都调用 wait,如果资源可用,则允许他们继续。如果不是,它们将被阻止。当每个人都完成他们调用的资源时 signal.

所以,您所看到的是预期的,因为您将信号量设置为就绪标志,但将其用作访问限制(因为您先调用 wait)。

所以我更正了我的代码以向您展示我是如何修复它的(感谢@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)
  }
}