When to use Semaphore instead of Dispatch Group?

I would suggest that I know how to work with DispatchGroup , to understand the problem I tried:

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

and the result is the expected -:

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

To use Semaphore, I implemented:

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

and called it in the method viewDidLoad. Result:

performUsingSemaphore() DispatchQueue 1: 1
performUsingSemaphore() DispatchQueue 1: 2
performUsingSemaphore() DispatchQueue 1: 3
performUsingSemaphore() DispatchQueue 2: 1
performUsingSemaphore() DispatchQueue 2: 2
performUsingSemaphore() DispatchQueue 2: 3

Conceptually, both DispachGroup and Semaphore teams accomplish the same goal (if I do not understand something).

Honestly, I am unfamiliar with: when to use Semaphore, especially when working with DispachGroup - it probably fixes the problem.

What role am I missing?

+4
source share
4 answers

Conceptually, both DispachGroup and Semaphore teams accomplish the same goal (if I do not understand something).

The above is not entirely true. You can use the semaphore to do the same thing as the sending group, but this is much more general.

, , , , , , - .

, . Apple .

, :

  • wait , , , - .

  • signal , , .

, . , , , . - , ..

, , N . N, N , , , , N . N = 1. .

. sempahore 0, - , , . , .

gotchas. , , , . , , , , . , , Dispatch . , , . , . , .

- , , - , . () , , , " " .

+5

, . , .

,

func performUsingGroup() {
    let dq1 = DispatchQueue.global(qos: .default)
    let dq2 = DispatchQueue.global(qos: .default)
    let group = DispatchGroup()

    for i in 1...3 {
        group.enter()
        dq1.async {
            print("\(#function) DispatchQueue 1: \(i)")
            group.leave()
        }
    }
    for i in 1...3 {
        group.enter()
        dq2.async {
            print("\(#function) DispatchQueue 2: \(i)")
            group.leave()
        }
    }

    group.notify(queue: DispatchQueue.main) {
        print("done by group")
    }
}

func performUsingSemaphore() {
    let dq1 = DispatchQueue.global(qos: .default)
    let dq2 = DispatchQueue.global(qos: .default)
    let semaphore = DispatchSemaphore(value: 1)

    for i in 1...3 {
        dq1.async {
            _ = semaphore.wait(timeout: DispatchTime.distantFuture)
            print("\(#function) DispatchQueue 1: \(i)")
            semaphore.signal()
        }
    }
    for i in 1...3 {
        dq2.async {
            _ = semaphore.wait(timeout: DispatchTime.distantFuture)
            print("\(#function) DispatchQueue 2: \(i)")
            semaphore.signal()
        }
    }
}
+4

, , . . wait , . a wait , .

, , . - 1, .

, , .

+4

- , , :

func myFunction() {
    semaphore.wait()
    // access the shared resource
    semaphore.signal()
}

myFunction , . , .

, .

.

- . , .

, , GCD.

-, signal wait , , , , .

+3

Source: https://habr.com/ru/post/1696319/


All Articles