Creating semaphore with initial value of 0 make issues with execution

别来无恙 提交于 2019-12-11 00:47:59

问题


I'm learning GCD and got question about semaphore. Here is my code:

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)
  }

If I run this code so nothing from semaphoreTask is printed in the console, but if I change

semaphore = dispatch_semaphore_create(0)

to

semaphore = dispatch_semaphore_create(1)

Everything starts work well.

The question is why should I write dispatch_semaphore_create(1) but not 0?

Thank you!


回答1:


You can use the semaphore in 2 different ways:

  1. To say when work or a resource is ready. In this case you start the semaphore at 0. The creator calls signal when something is ready. The consumer calls wait to wait for the expected item / resource.
  2. To limit the number of concurrent operations / requests / usages. In this case you start the semaphore at a positive value, like 4. The users each call wait and if resource is available they are allowed to continue. If not they are blocked. When each has finished with the resource they call signal.

So, what you see it expected because you're setting the semaphore up as a ready flag but using it as an access limit (because you call wait first).




回答2:


So I corrected my code to show you how I fixed it (thanks to @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)
  }
}


来源:https://stackoverflow.com/questions/37154877/creating-semaphore-with-initial-value-of-0-make-issues-with-execution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!