title: When to use Semaphore instead of Dispatch Group?
body: <p>I would assume that I am aware of how to work with <a href="https://developer.apple.com/documentation/dispatch/dispatchgroup" rel="noreferrer">DispatchGroup</a>, for understanding the issue, I've tried:</p>
  
  <pre><code>class ViewController: UIViewController {
      override func viewDidLoad() {
          super.viewDidLoad()
  
          performUsingGroup()
      }
  
      func performUsingGroup() {
          let dq1 = DispatchQueue.global(qos: .userInitiated)
          let dq2 = DispatchQueue.global(qos: .userInitiated)
  
          let group = DispatchGroup()
  
          group.enter()
          dq1.async {
              for i in 1...3 {
                  print("\(#function) DispatchQueue 1: \(i)")
              }
              group.leave()
          }
  
          group.wait()
  
          dq2.async {
              for i in 1...3 {
                  print("\(#function) DispatchQueue 2: \(i)")
              }
          }
  
          group.notify(queue: DispatchQueue.main) {
              print("done by group")
          }
      }
  }
  </code></pre>
  
  <p>and the result -as expected- is:</p>
  
  <pre><code>performUsingGroup() DispatchQueue 1: 1
  performUsingGroup() DispatchQueue 1: 2
  performUsingGroup() DispatchQueue 1: 3
  performUsingGroup() DispatchQueue 2: 1
  performUsingGroup() DispatchQueue 2: 2
  performUsingGroup() DispatchQueue 2: 3
  done by group
  </code></pre>
  
  <p>For using the Semaphore, I implemented:</p>
  
  <pre><code>func performUsingSemaphore() {
      let dq1 = DispatchQueue.global(qos: .userInitiated)
      let dq2 = DispatchQueue.global(qos: .userInitiated)
  
      let semaphore = DispatchSemaphore(value: 1)
  
      dq1.async {
          semaphore.wait()
          for i in 1...3 {
              print("\(#function) DispatchQueue 1: \(i)")
          }
          semaphore.signal()
      }
  
      dq2.async {
          semaphore.wait()
          for i in 1...3 {
              print("\(#function) DispatchQueue 2: \(i)")
          }
          semaphore.signal()
      }
  }
  </code></pre>
  
  <p>and called it in the <code>viewDidLoad</code> method. The result is:</p>
  
  <pre><code>performUsingSemaphore() DispatchQueue 1: 1
  performUsingSemaphore() DispatchQueue 1: 2
  performUsingSemaphore() DispatchQueue 1: 3
  performUsingSemaphore() DispatchQueue 2: 1
  performUsingSemaphore() DispatchQueue 2: 2
  performUsingSemaphore() DispatchQueue 2: 3
  </code></pre>
  
  <p>Conceptually, both of DispachGroup and Semaphore serve the same purpose (unless I misunderstand something).</p>
  
  <p>Honestly, I am unfamiliar with: when to use the Semaphore, especially when workin with DispachGroup -probably- handles the issue.</p>
  
  <p>What is the part that I am missing?</p>