Sobes.tech
Middle

What is a semaphore in the context of programming?

sobes.tech AI

Answer from AI

Semaphore is a primitive synchronization tool for threads that manages access to a limited resource. It maintains an integer counter.

Main operations:

  • wait() (or P / acquire): Decreases the counter by 1. If the counter becomes negative, the thread is blocked until another thread performs signal().
  • signal() (or V / release): Increases the counter by 1. If there are blocked threads, one of them is unblocked.

Types of semaphores:

  • Binary semaphore (mutex): The counter takes values 0 or 1. Used to ensure mutual exclusion — only one thread can access the resource at a time.
  • Counting semaphore: The counter can take values from 0 to N. Used to control access to a pool of resources with a limited number of available elements.

Example of usage in Swift to limit the number of tasks running simultaneously:

// Creating a semaphore that allows up to 3 concurrent accesses
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Task 1
    semaphore.wait() // Decrease the counter, block if more than 3 tasks are running
    print("Task 1 started")
    Thread.sleep(forTimeInterval: 2) // Simulate work
    print("Task 1 completed")
    semaphore.signal() // Increase the counter, unblock waiting tasks
}

DispatchQueue.global().async {
    // Task 2
    semaphore.wait()
    print("Task 2 started")
    Thread.sleep(forTimeInterval: 3)
    print("Task 2 completed")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Task 3
    semaphore.wait()
    print("Task 3 started")
    Thread.sleep(forTimeInterval: 1)
    print("Task 3 completed")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Task 4 (will wait until a slot is free)
    semaphore.wait()
    print("Task 4 started")
    Thread.sleep(forTimeInterval: 2)
    print("Task 4 completed")
    semaphore.signal()
}

// Wait for all tasks to finish for demonstration
// Use more reliable synchronization mechanisms in real code
Thread.sleep(forTimeInterval: 5)