wm.p1us
wm.p1us

Reputation: 2059

Creating semaphore with initial value of 0 make issues with execution

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!

Upvotes: 3

Views: 5773

Answers (2)

wm.p1us
wm.p1us

Reputation: 2059

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

Upvotes: 0

Wain
Wain

Reputation: 119031

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

Upvotes: 17

Related Questions