Exemples de Multithreading macOS Swift

Exemples de multithreading macOS Swift incluant la création de threads, la synchronisation avec verrous et l'utilisation de pool de threads

Key Facts

Category
Swift
Items
3
Format Families
sample

Sample Overview

Exemples de multithreading macOS Swift incluant la création de threads, la synchronisation avec verrous et l'utilisation de pool de threads This sample set belongs to Swift and can be used to test related workflows inside Elysia Tools.

💻 Création de Threads swift

🟡 intermediate ⭐⭐⭐

Créer et gérer des threads en utilisant la classe Thread et DispatchQueue pour l'exécution de tâches simultanées

⏱️ 30 min 🏷️ swift, macos, multithreading, concurrency
Prerequisites: Intermediate Swift, Concurrency concepts
// macOS Swift Thread Creation Examples
// Using Foundation and Dispatch frameworks

import Foundation

// 1. Basic Thread using Thread Class
class BasicThread {

    // Create and start a thread using Thread class
    static func createBasicThread() {
        print("\n--- Basic Thread ---")

        let thread = Thread {
            print("Thread running: \(Thread.current)")
            print("Is main thread: \(Thread.isMainThread)")
            for i in 1...5 {
                print("Thread count: \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        thread.start()
        thread.join() // Wait for thread to complete
        print("Thread finished")
    }

    // Thread with parameters
    static func createThreadWithParameters() {
        print("\n--- Thread with Parameters ---")

        let thread = Thread {
            (name: String, count: Int) in
            for i in 1...count {
                print("\(name): \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        // Thread doesn't directly support init with parameters
        // Use a closure that captures variables
        let workerThread = Thread {
            let name = "Worker"
            let count = 3
            for i in 1...count {
                print("\(name): \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        workerThread.start()
        workerThread.join()
    }

    // Detached thread (fire and forget)
    static func createDetachedThread() {
        print("\n--- Detached Thread ---")

        Thread.detachNewThread {
            print("Detached thread executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Detached thread done")
        }

        print("Main thread continues immediately")
        Thread.sleep(forTimeInterval: 0.3) // Wait to see detached thread finish
    }

    // Multiple threads
    static func createMultipleThreads() {
        print("\n--- Multiple Threads ---")

        var threads: [Thread] = []

        for i in 1...3 {
            let thread = Thread {
                print("Thread \(i) started")
                for j in 1...3 {
                    print("Thread \(i): Step \(j)")
                    Thread.sleep(forTimeInterval: 0.1)
                }
                print("Thread \(i) finished")
            }
            threads.append(thread)
        }

        // Start all threads
        for thread in threads {
            thread.start()
        }

        // Wait for all threads to complete
        for thread in threads {
            thread.join()
        }

        print("All threads completed")
    }
}

// 2. DispatchQueue (Modern Swift Threading)
class DispatchQueueExample {

    // Global queue (background thread)
    static func globalQueueExample() {
        print("\n--- Global Queue ---")

        DispatchQueue.global(qos: .userInitiated).async {
            print("Background task executing")
            print("Is main thread: \(Thread.isMainThread)")

            // Simulate work
            Thread.sleep(forTimeInterval: 0.2)

            DispatchQueue.main.async {
                print("Back to main thread for UI update")
            }
        }

        Thread.sleep(forTimeInterval: 0.3)
    }

    // Custom queue
    static func customQueueExample() {
        print("\n--- Custom Queue ---")

        let customQueue = DispatchQueue(label: "com.example.customQueue", qos: .utility)

        customQueue.async {
            print("Task 1 on custom queue")
            Thread.sleep(forTimeInterval: 0.1)
        }

        customQueue.async {
            print("Task 2 on custom queue")
            Thread.sleep(forTimeInterval: 0.1)
        }

        customQueue.sync {
            print("Sync task on custom queue")
        }

        print("Custom queue tasks dispatched")
        Thread.sleep(forTimeInterval: 0.3)
    }

    // Serial queue
    static func serialQueueExample() {
        print("\n--- Serial Queue ---")

        let serialQueue = DispatchQueue(label: "com.example.serialQueue")

        print("Dispatching tasks to serial queue")

        serialQueue.async {
            for i in 1...3 {
                print("Task 1: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        serialQueue.async {
            for i in 1...3 {
                print("Task 2: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        serialQueue.async {
            for i in 1...3 {
                print("Task 3: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        Thread.sleep(forTimeInterval: 0.6)
        print("Serial queue tasks completed")
    }

    // Concurrent queue
    static func concurrentQueueExample() {
        print("\n--- Concurrent Queue ---")

        let concurrentQueue = DispatchQueue(
            label: "com.example.concurrentQueue",
            attributes: .concurrent
        )

        print("Dispatching tasks to concurrent queue")

        let group = DispatchGroup()

        for i in 1...3 {
            group.enter()
            concurrentQueue.async {
                for j in 1...3 {
                    print("Task \(i): Step \(j)")
                    Thread.sleep(forTimeInterval: 0.05)
                }
                group.leave()
            }
        }

        group.notify(queue: .main) {
            print("All concurrent tasks completed")
        }

        group.wait()
    }

    // Quality of Service levels
    static func qosExample() {
        print("\n--- Quality of Service (QoS) ---")

        DispatchQueue.global(qos: .userInteractive).async {
            print("User Interactive - Highest priority")
        }

        DispatchQueue.global(qos: .userInitiated).async {
            print("User Initiated - High priority")
        }

        DispatchQueue.global(qos: .utility).async {
            print("Utility - Low priority")
        }

        DispatchQueue.global(qos: .background).async {
            print("Background - Lowest priority")
        }

        Thread.sleep(forTimeInterval: 0.1)
    }
}

// 3. Operation and OperationQueue
class OperationExample {

    // Basic Operation
    static func basicOperation() {
        print("\n--- Basic Operation ---")

        let operation = BlockOperation {
            print("Operation executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Operation completed")
        }

        operation.start()
        operation.waitUntilFinished()
    }

    // Multiple operations
    static func multipleOperations() {
        print("\n--- Multiple Operations ---")

        let queue = OperationQueue()

        for i in 1...3 {
            let operation = BlockOperation {
                print("Operation \(i) executing")
                Thread.sleep(forTimeInterval: 0.1)
                print("Operation \(i) completed")
            }
            queue.addOperation(operation)
        }

        queue.waitUntilAllOperationsAreFinished()
        print("All operations completed")
    }

    // Operation with dependencies
    static func operationDependencies() {
        print("\n--- Operation Dependencies ---")

        let queue = OperationQueue()

        let op1 = BlockOperation {
            print("Operation 1 (Download)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        let op2 = BlockOperation {
            print("Operation 2 (Process)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        let op3 = BlockOperation {
            print("Operation 3 (Save)")
            Thread.sleep(forTimeInterval: 0.1)
        }

        // Set dependencies: op1 -> op2 -> op3
        op2.addDependency(op1)
        op3.addDependency(op2)

        queue.addOperations([op3, op2, op1], waitUntilFinished: false)

        print("Operations queued with dependencies")
        queue.waitUntilAllOperationsAreFinished()
        print("Dependent operations completed")
    }

    // Custom Operation
    class CustomOperation: Operation {
        let name: String
        let duration: TimeInterval

        init(name: String, duration: TimeInterval) {
            self.name = name
            self.duration = duration
            super.init()
        }

        override func main() {
            if isCancelled { return }

            print("\(name) started")

            for i in 1...3 {
                if isCancelled {
                    print("\(name) cancelled")
                    return
                }
                print("\(name): Progress \(i)")
                Thread.sleep(forTimeInterval: duration / 3)
            }

            print("\(name) completed")
        }
    }

    static func customOperationExample() {
        print("\n--- Custom Operation ---")

        let queue = OperationQueue()

        let op1 = CustomOperation(name: "Task A", duration: 0.3)
        let op2 = CustomOperation(name: "Task B", duration: 0.2)

        queue.addOperations([op1, op2], waitUntilFinished: true)
        print("Custom operations completed")
    }
}

// 4. Thread Local Storage
class ThreadLocalStorage {

    static func threadLocalExample() {
        print("\n--- Thread Local Storage ---")

        // Using Thread.threadDictionary
        let thread = Thread {
            // Store thread-local data
            Thread.current.threadDictionary["threadID"] = "Thread-1"
            Thread.current.threadDictionary["counter"] = 0

            print("Thread ID: \(Thread.current.threadDictionary["threadID"] ?? "N/A")")

            for i in 1...3 {
                var count = Thread.current.threadDictionary["counter"] as? Int ?? 0
                count += 1
                Thread.current.threadDictionary["counter"] = count
                print("Local counter: \(count)")
                Thread.sleep(forTimeInterval: 0.05)
            }

            print("Final counter: \(Thread.current.threadDictionary["counter"] ?? "N/A")")
        }

        thread.start()
        thread.join()
    }
}

// 5. Thread Priority
class ThreadPriority {

    static func priorityExample() {
        print("\n--- Thread Priority ---")

        let highPriorityThread = Thread {
            print("High priority thread started")
            for i in 1...3 {
                print("High: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        let lowPriorityThread = Thread {
            print("Low priority thread started")
            for i in 1...3 {
                print("Low: \(i)")
                Thread.sleep(forTimeInterval: 0.05)
            }
        }

        // Set thread priorities (0.0 to 1.0)
        highPriorityThread.threadPriority = 1.0
        lowPriorityThread.threadPriority = 0.1

        highPriorityThread.start()
        lowPriorityThread.start()

        highPriorityThread.join()
        lowPriorityThread.join()
    }
}

// 6. Cancel Thread
class ThreadCancellation {

    static func cancellationExample() {
        print("\n--- Thread Cancellation ---")

        var shouldStop = false

        let thread = Thread {
            print("Worker thread started")

            for i in 1...10 {
                if shouldStop {
                    print("Thread cancelled at iteration \(i)")
                    return
                }

                print("Working... \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }

            print("Worker thread completed normally")
        }

        thread.start()

        // Cancel after 0.3 seconds
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
            print("Sending cancellation signal")
            shouldStop = true
        }

        thread.join()
        print("Thread handling completed")
    }
}

// 7. Async/Await (Swift 5.5+)
@available(macOS 12.0, *)
class ModernConcurrency {

    static func asyncAwaitExample() async {
        print("\n--- Async/Await ---")

        // Simple async function
        func fetchData() async -> String {
            print("Fetching data...")
            try? await Task.sleep(nanoseconds: 200_000_000)
            return "Data fetched"
        }

        let result = await fetchData()
        print(result)

        // Concurrent tasks
        async let task1 = fetchData()
        async let task2 = fetchData()

        let (r1, r2) = await (task1, task2)
        print("Results: \(r1), \(r2)")
    }

    // Task Group
    static func taskGroupExample() async {
        print("\n--- Task Group ---")

        let results = await withTaskGroup(of: Int.self) { group in
            var results: [Int] = []

            for i in 1...3 {
                group.addTask {
                    print("Task \(i) started")
                    try? await Task.sleep(nanoseconds: 100_000_000)
                    print("Task \(i) completed")
                    return i * 10
                }
            }

            for await result in group {
                results.append(result)
            }

            return results
        }

        print("Task group results: \(results)")
    }

    // Actor (Thread-safe reference type)
    actor Counter {
        private var value = 0

        func increment() -> Int {
            value += 1
            return value
        }

        func getValue() -> Int {
            return value
        }
    }

    static func actorExample() async {
        print("\n--- Actor Example ---")

        let counter = Counter()

        await counter.increment()
        await counter.increment()
        await counter.increment()

        let finalValue = await counter.getValue()
        print("Counter value: \(finalValue)")
    }
}

// 8. Thread with Completion Handler
class ThreadWithCompletion {

    static func completionExample() {
        print("\n--- Thread with Completion ---")

        func performWork(completion: @escaping (String) -> Void) {
            DispatchQueue.global().async {
                print("Work started")
                Thread.sleep(forTimeInterval: 0.2)
                let result = "Work completed"

                DispatchQueue.main.async {
                    completion(result)
                }
            }
        }

        performWork { result in
            print("Completion: \(result)")
        }

        Thread.sleep(forTimeInterval: 0.3)
    }
}

// 9. Run Loop
class RunLoopExample {

    static func runLoopTimerExample() {
        print("\n--- Run Loop Timer ---")

        var count = 0

        let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            count += 1
            print("Timer tick: \(count)")

            if count >= 3 {
                print("Timer finished")
                // In real app, you'd invalidate the timer
            }
        }

        // Run the loop for a short time
        RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.4))
        timer.invalidate()
    }
}

// Main demonstration
func demonstrateThreadCreation() {
    print("=== macOS Swift Thread Creation Examples ===")

    // 1. Basic Thread
    BasicThread.createBasicThread()
    BasicThread.createThreadWithParameters()
    BasicThread.createDetachedThread()
    BasicThread.createMultipleThreads()

    // 2. DispatchQueue
    DispatchQueueExample.globalQueueExample()
    DispatchQueueExample.customQueueExample()
    DispatchQueueExample.serialQueueExample()
    DispatchQueueExample.concurrentQueueExample()
    DispatchQueueExample.qosExample()

    // 3. Operation
    OperationExample.basicOperation()
    OperationExample.multipleOperations()
    OperationExample.operationDependencies()
    OperationExample.customOperationExample()

    // 4. Thread Local Storage
    ThreadLocalStorage.threadLocalExample()

    // 5. Thread Priority
    ThreadPriority.priorityExample()

    // 6. Cancellation
    ThreadCancellation.cancellationExample()

    // 7. Completion Handler
    ThreadWithCompletion.completionExample()

    // 8. Run Loop
    RunLoopExample.runLoopTimerExample()

    // 9. Modern Concurrency (if available)
    if #available(macOS 12.0, *) {
        Task {
            await ModernConcurrency.asyncAwaitExample()
            await ModernConcurrency.taskGroupExample()
            await ModernConcurrency.actorExample()
        }
    }

    print("\n=== All Thread Creation Examples Completed ===")
}

// Run demonstration
demonstrateThreadCreation()

💻 Synchronisation de Threads swift

🟡 intermediate ⭐⭐⭐⭐

Synchroniser l'accès des threads en utilisant des verrous, sémaphores, barrières et variables de condition

⏱️ 40 min 🏷️ swift, macos, multithreading, synchronization
Prerequisites: Intermediate Swift, Thread concepts
// macOS Swift Thread Synchronization Examples
// Using Foundation and Dispatch frameworks

import Foundation

// 1. NSLock - Basic Mutex Lock
class LockExample {

    var counter = 0
    let lock = NSLock()

    // Unsafe increment (race condition)
    func unsafeIncrement() {
        let temp = counter
        Thread.sleep(forTimeInterval: 0.00001) // Simulate context switch
        counter = temp + 1
    }

    // Safe increment with lock
    func safeIncrement() {
        lock.lock()
        let temp = counter
        Thread.sleep(forTimeInterval: 0.00001)
        counter = temp + 1
        lock.unlock()
    }

    static func raceConditionDemo() {
        print("\n--- Race Condition Demo ---")

        let example = LockExample()

        // Unsafe version
        print("Unsafe increment:")
        var threads: [Thread] = []
        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.unsafeIncrement()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Unsafe result: \(example.counter) (expected: 1000)")

        // Reset
        example.counter = 0
        threads.removeAll()

        // Safe version
        print("\nSafe increment with lock:")
        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.safeIncrement()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Safe result: \(example.counter) (expected: 1000)")
    }

    // Try lock
    static func tryLockDemo() {
        print("\n--- Try Lock Demo ---")

        let lock = NSLock()
        var result = ""

        let thread1 = Thread {
            if lock.try() {
                print("Thread 1: Acquired lock immediately")
                Thread.sleep(forTimeInterval: 0.2)
                print("Thread 1: Releasing lock")
                lock.unlock()
            } else {
                print("Thread 1: Lock unavailable")
                result = "failed"
            }
        }

        let thread2 = Thread {
            Thread.sleep(forTimeInterval: 0.1)
            if lock.try() {
                print("Thread 2: Acquired lock")
                lock.unlock()
            } else {
                print("Thread 2: Lock busy, giving up")
                result = "busy"
            }
        }

        thread1.start()
        thread2.start()

        thread1.join()
        thread2.join()

        print("Result: \(result)")
    }
}

// 2. NSRecursiveLock
class RecursiveLockExample {

    let lock = NSRecursiveLock()
    var depth = 0

    func recursiveMethod(_ maxDepth: Int) {
        lock.lock()
        defer { lock.unlock() }

        depth += 1
        print("Recursive depth: \(depth)")

        if depth < maxDepth {
            recursiveMethod(maxDepth)
        }

        depth -= 1
    }

    static func recursiveLockDemo() {
        print("\n--- Recursive Lock Demo ---")

        let example = RecursiveLockExample()

        let thread = Thread {
            example.recursiveMethod(5)
        }

        thread.start()
        thread.join()

        print("Recursive method completed")
    }
}

// 3. NSConditionLock
class ConditionLockExample {

    let conditionLock = NSConditionLock(condition: 0)
    var data: String?

    // Producer
    func produce(_ value: String) {
        conditionLock.lock(whenCondition: 0) // Wait until condition is 0 (empty)
        data = value
        print("Produced: \(value)")
        conditionLock.unlock(withCondition: 1) // Set condition to 1 (has data)
    }

    // Consumer
    func consume() -> String? {
        conditionLock.lock(whenCondition: 1) // Wait until condition is 1 (has data)
        let value = data
        print("Consumed: \(value ?? "nil")")
        data = nil
        conditionLock.unlock(withCondition: 0) // Set condition back to 0 (empty)
        return value
    }

    static func conditionLockDemo() {
        print("\n--- Condition Lock Demo ---")

        let example = ConditionLockExample()
        var consumedValue: String?

        // Consumer thread
        let consumer = Thread {
            Thread.sleep(forTimeInterval: 0.1) // Wait for producer
            consumedValue = example.consume()
        }

        // Producer thread
        let producer = Thread {
            example.produce("Test Data")
        }

        consumer.start()
        producer.start()

        consumer.join()
        producer.join()

        print("Final consumed value: \(consumedValue ?? "nil")")
    }
}

// 4. DispatchQueue Barrier (Reader-Writer Lock)
class BarrierExample {

    private let queue = DispatchQueue(
        label: "com.example.barrierQueue",
        attributes: .concurrent
    )

    private var data: [String] = []

    // Read operation (concurrent)
    func read(completion: @escaping ([String]) -> Void) {
        queue.async {
            print("Reading data: \(self.data)")
            completion(self.data)
        }
    }

    // Write operation (exclusive with barrier)
    func write(_ value: String) {
        queue.async(flags: .barrier) {
            print("Writing: \(value)")
            self.data.append(value)
            Thread.sleep(forTimeInterval: 0.05) // Simulate write time
        }
    }

    static func barrierDemo() {
        print("\n--- Barrier Demo ---")

        let example = BarrierExample()

        // Initial writes
        example.write("Item 1")
        example.write("Item 2")

        Thread.sleep(forTimeInterval: 0.2)

        // Concurrent reads
        print("\nStarting concurrent reads:")
        let group = DispatchGroup()

        for i in 1...3 {
            group.enter()
            example.read { data in
                print("Reader \(i) got: \(data)")
                group.leave()
            }
        }

        // Write during reads (will wait)
        group.enter()
        queue.async(flags: .barrier) {
            example.write("Item 3 (barrier)")
            group.leave()
        }

        group.wait()
        print("\nBarrier demo completed")
    }
}

// 5. NSCondition
class ConditionExample {

    let condition = NSCondition()
    var isReady = false
    var data: String?

    // Wait for data
    func waitForData() -> String? {
        condition.lock()

        while !isReady {
            print("Waiting for data...")
            condition.wait()
        }

        let value = data
        isReady = false
        condition.unlock()
        return value
    }

    // Signal data ready
    func signalData(_ value: String) {
        condition.lock()
        data = value
        isReady = true
        print("Signaling data: \(value)")
        condition.signal()
        condition.unlock()
    }

    static func conditionDemo() {
        print("\n--- Condition Demo ---")

        let example = ConditionExample()

        // Consumer thread
        let consumer = Thread {
            if let data = example.waitForData() {
                print("Consumer received: \(data)")
            }
        }

        // Producer thread
        let producer = Thread {
            Thread.sleep(forTimeInterval: 0.2)
            example.signalData("Hello from producer!")
        }

        consumer.start()
        producer.start()

        consumer.join()
        producer.join()

        print("Condition demo completed")
    }
}

// 6. DispatchSemaphore
class SemaphoreExample {

    let semaphore = DispatchSemaphore(value: 3) // Max 3 concurrent accesses
    var activeCount = 0

    func accessResource(id: Int) {
        semaphore.wait() // Acquire

        activeCount += 1
        print("Resource \(id) accessing. Active: \(activeCount)")

        Thread.sleep(forTimeInterval: 0.2)

        activeCount -= 1
        print("Resource \(id) releasing. Active: \(activeCount)")

        semaphore.signal() // Release
    }

    static func semaphoreDemo() {
        print("\n--- Semaphore Demo ---")

        let example = SemaphoreExample()
        var threads: [Thread] = []

        // Create 5 threads but only 3 can access at a time
        for i in 1...5 {
            let thread = Thread {
                example.accessResource(id: i)
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Semaphore demo completed")
    }

    // Producer-Consumer with semaphores
    static func producerConsumerSemaphore() {
        print("\n--- Producer-Consumer with Semaphore ---")

        let bufferSemaphore = DispatchSemaphore(value: 5) // Buffer size
        let itemSemaphore = DispatchSemaphore(value: 0) // Items available
        var buffer: [Int] = []

        // Producer
        let producer = Thread {
            for i in 1...5 {
                bufferSemaphore.wait() // Wait for space
                buffer.append(i)
                print("Produced: \(i), Buffer: \(buffer)")
                itemSemaphore.signal() // Signal item available
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // Consumer
        let consumer = Thread {
            for _ in 1...5 {
                itemSemaphore.wait() // Wait for item
                if let item = buffer.first {
                    buffer.removeFirst()
                    print("Consumed: \(item), Buffer: \(buffer)")
                }
                bufferSemaphore.signal() // Signal space available
                Thread.sleep(forTimeInterval: 0.15)
            }
        }

        consumer.start()
        producer.start()

        producer.join()
        consumer.join()

        print("Producer-Consumer completed")
    }
}

// 7. Synchronized Block (using objc_sync_enter/exit)
class SynchronizedExample {

    var sharedResource = 0

    func safeOperation() {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        let temp = sharedResource
        Thread.sleep(forTimeInterval: 0.0001)
        sharedResource = temp + 1
    }

    static func synchronizedDemo() {
        print("\n--- Synchronized Block Demo ---")

        let example = SynchronizedExample()
        var threads: [Thread] = []

        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.safeOperation()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Synchronized result: \(example.sharedResource)")
    }
}

// 8. DispatchQueue.sync (Barrier-free synchronization)
class SyncDispatchExample {

    private let queue = DispatchQueue(label: "com.example.syncQueue")
    private var counter = 0

    func increment() {
        queue.sync {
            counter += 1
        }
    }

    func getCount() -> Int {
        return queue.sync {
            counter
        }
    }

    static func syncDemo() {
        print("\n--- Sync Dispatch Demo ---")

        let example = SyncDispatchExample()
        var threads: [Thread] = []

        for i in 1...5 {
            let thread = Thread {
                for _ in 1...100 {
                    example.increment()
                }
                print("Thread \(i) completed")
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Final count: \(example.getCount())")
    }
}

// 9. Atomic Operations (using OSAtomic)
class AtomicExample {

    // Using DispatchQueue for atomic-like behavior
    private let queue = DispatchQueue(label: "com.example.atomicQueue")
    private var _value = 0

    var value: Int {
        get { return queue.sync { _value } }
        set { queue.sync { _value = newValue } }
    }

    func incrementAndGet() -> Int {
        return queue.sync {
            _value += 1
            return _value
        }
    }

    static func atomicDemo() {
        print("\n--- Atomic Operations Demo ---")

        let example = AtomicExample()
        var threads: [Thread] = []

        for _ in 0..<10 {
            let thread = Thread {
                for _ in 0..<100 {
                    example.incrementAndGet()
                }
            }
            threads.append(thread)
            thread.start()
        }

        for thread in threads {
            thread.join()
        }

        print("Atomic result: \(example.value)")
    }
}

// 10. Deadlock Prevention
class DeadlockExample {

    let lock1 = NSLock()
    let lock2 = NSLock()

    // Deadlock scenario
    func deadlockScenario() {
        print("\n--- Deadlock Scenario ---")

        let thread1 = Thread {
            print("Thread 1: Acquiring lock 1")
            self.lock1.lock()
            print("Thread 1: Lock 1 acquired")

            Thread.sleep(forTimeInterval: 0.1)

            print("Thread 1: Waiting for lock 2")
            self.lock2.lock()
            print("Thread 1: Lock 2 acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 1: Completed")
        }

        let thread2 = Thread {
            print("Thread 2: Acquiring lock 2")
            self.lock2.lock()
            print("Thread 2: Lock 2 acquired")

            Thread.sleep(forTimeInterval: 0.1)

            print("Thread 2: Waiting for lock 1")
            self.lock1.lock()
            print("Thread 2: Lock 1 acquired")

            self.lock1.unlock()
            self.lock2.unlock()
            print("Thread 2: Completed")
        }

        thread1.start()
        thread2.start()

        // This will deadlock - in practice, use timeout
        // For demo, we'll kill threads after timeout
        Thread.sleep(forTimeInterval: 0.3)
        print("Deadlock occurred (as expected)")
    }

    // Deadlock prevention with lock ordering
    func safeLockOrdering() {
        print("\n--- Safe Lock Ordering ---")

        let thread1 = Thread {
            print("Thread 1: Acquiring locks in order 1->2")
            self.lock1.lock()
            self.lock2.lock()
            print("Thread 1: Both locks acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 1: Completed")
        }

        let thread2 = Thread {
            print("Thread 2: Acquiring locks in order 1->2")
            self.lock1.lock()
            self.lock2.lock()
            print("Thread 2: Both locks acquired")

            self.lock2.unlock()
            self.lock1.unlock()
            print("Thread 2: Completed")
        }

        thread1.start()
        thread2.start()

        thread1.join()
        thread2.join()

        print("Safe ordering completed")
    }
}

// Main demonstration
func demonstrateThreadSynchronization() {
    print("=== macOS Swift Thread Synchronization Examples ===")

    // 1. Basic Lock
    LockExample.raceConditionDemo()
    LockExample.tryLockDemo()

    // 2. Recursive Lock
    RecursiveLockExample.recursiveLockDemo()

    // 3. Condition Lock
    ConditionLockExample.conditionLockDemo()

    // 4. Barrier
    BarrierExample.barrierDemo()

    // 5. Condition Variable
    ConditionExample.conditionDemo()

    // 6. Semaphore
    SemaphoreExample.semaphoreDemo()
    SemaphoreExample.producerConsumerSemaphore()

    // 7. Synchronized
    SynchronizedExample.synchronizedDemo()

    // 8. Sync Dispatch
    SyncDispatchExample.syncDemo()

    // 9. Atomic
    AtomicExample.atomicDemo()

    // 10. Deadlock
    DeadlockExample().deadlockScenario()
    DeadlockExample().safeLockOrdering()

    print("\n=== All Thread Synchronization Examples Completed ===")
}

// Run demonstration
demonstrateThreadSynchronization()

💻 Pool de Threads swift

🔴 complex ⭐⭐⭐⭐⭐

Implémenter le pattern de pool de threads pour une exécution efficace des tâches avec gestion des ressources

⏱️ 45 min 🏷️ swift, macos, multithreading, thread pool
Prerequisites: Advanced Swift, Thread concepts, Concurrency
// macOS Swift Thread Pool Examples
// Using OperationQueue and custom implementation

import Foundation

// 1. OperationQueue as Thread Pool
class OperationQueuePool {

    let queue: OperationQueue

    init(maxThreads: Int) {
        queue = OperationQueue()
        queue.maxConcurrentOperationCount = maxThreads
        queue.name = "com.example.operationPool"
    }

    func submit(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        queue.addOperation(operation)
    }

    func submitAndWait(_ tasks: [() -> Void]) {
        let operations = tasks.map { BlockOperation(block: $0) }
        queue.addOperations(operations, waitUntilFinished: true)
    }

    func shutdown() {
        queue.cancelAllOperations()
        queue.waitUntilAllOperationsAreFinished()
    }

    static func basicExample() {
        print("\n--- OperationQueue Pool ---")

        let pool = OperationQueuePool(maxThreads: 3)

        print("Submitting 10 tasks to pool of 3 threads")

        for i in 1...10 {
            pool.submit {
                print("Task \(i) executing on thread \(Thread.current.hashValue)")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) completed")
            }
        }

        pool.shutdown()
        print("All tasks completed")
    }
}

// 2. DispatchQueue Thread Pool
class DispatchQueuePool {

    private let workQueue: DispatchQueue
    private let semaphore: DispatchSemaphore

    init(maxThreads: Int) {
        workQueue = DispatchQueue(
            label: "com.example.dispatchPool",
            attributes: .concurrent
        )
        semaphore = DispatchSemaphore(value: maxThreads)
    }

    func submit(_ task: @escaping () -> Void) {
        workQueue.async {
            self.semaphore.wait()

            task()

            self.semaphore.signal()
        }
    }

    static func basicExample() {
        print("\n--- DispatchQueue Pool ---")

        let pool = DispatchQueuePool(maxThreads: 3)

        print("Submitting 8 tasks")

        for i in 1...8 {
            pool.submit {
                print("Task \(i) started")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) completed")
            }
        }

        Thread.sleep(forTimeInterval: 1.0) // Wait for completion
        print("DispatchQueue pool demo completed")
    }
}

// 3. Custom Thread Pool
class ThreadPool {

    private var threads: [Thread] = []
    private var taskQueue: [(String) -> Void] = []
    private let queueLock = NSLock()
    private let condition = NSCondition()
    private var isRunning = true

    init(threadCount: Int, name: String = "ThreadPool") {
        for i in 0..<threadCount {
            let thread = Thread {
                self.workerThread(id: i)
            }
            thread.name = "\(name)-\(i)"
            threads.append(thread)
        }
    }

    func start() {
        for thread in threads {
            thread.start()
        }
    }

    func submit(_ task: @escaping () -> Void) {
        queueLock.lock()
        taskQueue.append { _ in task() }
        queueLock.unlock()
        condition.signal()
    }

    func submitWithID(_ task: @escaping (String) -> Void) {
        queueLock.lock()
        taskQueue.append(task)
        queueLock.unlock()
        condition.signal()
    }

    func shutdown() {
        queueLock.lock()
        isRunning = false
        queueLock.unlock()
        condition.broadcast()

        for thread in threads {
            thread.join()
        }
    }

    private func workerThread(id: Int) {
        print("Worker thread \(id) started")

        while true {
            queueLock.lock()
            while taskQueue.isEmpty && isRunning {
                queueLock.unlock()
                condition.lock()
                condition.wait()
                condition.unlock()
                queueLock.lock()
            }

            if !isRunning {
                queueLock.unlock()
                break
            }

            let task = taskQueue.removeFirst()
            queueLock.unlock()

            task("Thread-\(id)")
        }

        print("Worker thread \(id) exiting")
    }

    static func basicExample() {
        print("\n--- Custom Thread Pool ---")

        let pool = ThreadPool(threadCount: 3, name: "CustomPool")
        pool.start()

        print("Submitting 10 tasks")

        for i in 1...10 {
            pool.submit {
                print("Task \(i) executing")
                Thread.sleep(forTimeInterval: 0.1)
                print("Task \(i) done")
            }
        }

        Thread.sleep(forTimeInterval: 0.5)
        pool.shutdown()
        print("Custom pool shutdown complete")
    }
}

// 4. Future/Promise Pattern
class Future<T> {
    private var result: T?
    private var error: Error?
    private let condition = NSCondition()
    private var isCompleted = false

    func complete(with value: T) {
        condition.lock()
        result = value
        isCompleted = true
        condition.broadcast()
        condition.unlock()
    }

    func fail(with error: Error) {
        condition.lock()
        self.error = error
        isCompleted = true
        condition.broadcast()
        condition.unlock()
    }

    func get() throws -> T {
        condition.lock()
        while !isCompleted {
            condition.wait()
        }

        defer { condition.unlock() }

        if let error = error {
            throw error
        }

        return result!
    }

    func get(timeout: TimeInterval) throws -> T? {
        condition.lock()
        while !isCompleted {
            if !condition.wait(until: Date().addingTimeInterval(timeout)) {
                condition.unlock()
                return nil // Timeout
            }
        }

        defer { condition.unlock() }

        if let error = error {
            throw error
        }

        return result
    }
}

class Promise<T> {
    let future = Future<T>()

    func succeed(_ value: T) {
        future.complete(with: value)
    }

    func fail(_ error: Error) {
        future.fail(with: error)
    }

    var getFuture: Future<T> {
        return future
    }
}

// Thread Pool with Futures
class FutureThreadPool {

    private let pool = ThreadPool(threadCount: 3)

    init() {
        pool.start()
    }

    func submit<T>(_ task: @escaping () throws -> T) -> Future<T> {
        let promise = Promise<T>()

        pool.submit {
            do {
                let result = try task()
                promise.succeed(result)
            } catch {
                promise.fail(error)
            }
        }

        return promise.getFuture
    }

    deinit {
        pool.shutdown()
    }

    static func futureExample() {
        print("\n--- Future/Promise Thread Pool ---")

        let pool = FutureThreadPool()

        // Submit tasks and get futures
        let future1 = pool.submit { () -> Int in
            print("Task 1 executing")
            Thread.sleep(forTimeInterval: 0.2)
            print("Task 1 done")
            return 42
        }

        let future2 = pool.submit { () -> String in
            print("Task 2 executing")
            Thread.sleep(forTimeInterval: 0.1)
            print("Task 2 done")
            return "Hello"
        }

        // Wait for results
        do {
            let result1 = try future1.get()
            print("Future 1 result: \(result1)")

            let result2 = try future2.get()
            print("Future 2 result: \(result2)")
        } catch {
            print("Error: \(error)")
        }
    }
}

// 5. Priority Thread Pool
class PriorityThreadPool {

    let queue = OperationQueue()
    let highPriorityQueue = OperationQueue()
    let lowPriorityQueue = OperationQueue()

    init() {
        highPriorityQueue.maxConcurrentOperationCount = 2
        lowPriorityQueue.maxConcurrentOperationCount = 2
        queue.maxConcurrentOperationCount = 3
    }

    func submitHigh(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .high
        highPriorityQueue.addOperation(operation)
    }

    func submitNormal(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .normal
        queue.addOperation(operation)
    }

    func submitLow(_ task: @escaping () -> Void) {
        let operation = BlockOperation(block: task)
        operation.queuePriority = .low
        lowPriorityQueue.addOperation(operation)
    }

    func waitForAll() {
        highPriorityQueue.waitUntilAllOperationsAreFinished()
        queue.waitUntilAllOperationsAreFinished()
        lowPriorityQueue.waitUntilAllOperationsAreFinished()
    }

    static func priorityExample() {
        print("\n--- Priority Thread Pool ---")

        let pool = PriorityThreadPool()

        print("Submitting tasks with different priorities")

        // Low priority tasks
        for i in 1...3 {
            pool.submitLow {
                print("Low priority task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // Normal priority tasks
        for i in 1...2 {
            pool.submitNormal {
                print("Normal priority task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        // High priority tasks
        pool.submitHigh {
            print("High priority task 1")
            Thread.sleep(forTimeInterval: 0.1)
        }

        pool.waitForAll()
        print("All priority tasks completed")
    }
}

// 6. Task Group (Modern Swift Concurrency)
@available(macOS 12.0, *)
class ModernTaskGroup {

    static func taskGroupExample() async {
        print("\n--- Modern Task Group ---")

        // Create task group
        await withTaskGroup(of: Int.self) { group in
            // Add tasks
            for i in 1...5 {
                group.addTask {
                    print("Task \(i) started")
                    try? await Task.sleep(nanoseconds: 100_000_000 * UInt64(i))
                    print("Task \(i) completed")
                    return i * 10
                }
            }

            // Collect results
            var results: [Int] = []
            for await result in group {
                results.append(result)
            }

            print("Task group results: \(results)")
        }
    }

    // Parallel map with task group
    static func parallelMapExample() async {
        print("\n--- Parallel Map ---")

        let items = [1, 2, 3, 4, 5]

        let results = await withTaskGroup(of: Int.self) { group in
            for item in items {
                group.addTask {
                    // Simulate async work
                    try? await Task.sleep(nanoseconds: 50_000_000)
                    return item * item
                }
            }

            var mapped: [Int] = []
            for await result in group {
                mapped.append(result)
            }
            return mapped.sorted()
        }

        print("Mapped results: \(results)")
    }

    // Concurrent data processing
    static func dataProcessingExample() async {
        print("\n--- Concurrent Data Processing ---")

        struct DataItem {
            let id: Int
            let value: String
        }

        let data = (1...10).map { DataItem(id: $0, value: "Item-\($0)") }

        let processed = await withTaskGroup(of: String.self) { group in
            for item in data {
                group.addTask {
                    // Simulate processing
                    try? await Task.sleep(nanoseconds: 30_000_000)
                    return "\(item.value)_processed"
                }
            }

            var results: [String] = []
            for await result in group {
                results.append(result)
            }
            return results
        }

        print("Processed \(processed.count) items")
    }
}

// 7. Work Stealing Thread Pool
class WorkStealingPool {

    private let globalQueue: DispatchQueue
    private let localQueues: [DispatchQueue]
    private let semaphore: DispatchSemaphore

    init(threadCount: Int) {
        globalQueue = DispatchQueue(label: "com.example.globalQueue")

        var queues: [DispatchQueue] = []
        for i in 0..<threadCount {
            let queue = DispatchQueue(
                label: "com.example.localQueue-\(i)",
                attributes: .concurrent
            )
            queues.append(queue)
        }
        localQueues = queues

        semaphore = DispatchSemaphore(value: threadCount)
    }

    func submit(task: @escaping () -> Void) {
        globalQueue.async {
            self.semaphore.wait()

            // In a real implementation, this would use work stealing
            // For simplicity, we just execute on a random local queue
            if let localQueue = self.localQueues.randomElement() {
                localQueue.async {
                    task()
                    self.semaphore.signal()
                }
            }
        }
    }

    static func workStealingExample() {
        print("\n--- Work Stealing Pool ---")

        let pool = WorkStealingPool(threadCount: 4)

        print("Submitting tasks to work stealing pool")

        for i in 1...12 {
            pool.submit(task: {
                print("Task \(i) executing")
                Thread.sleep(forTimeInterval: 0.05)
                print("Task \(i) done")
            })
        }

        Thread.sleep(forTimeInterval: 0.8)
        print("Work stealing demo completed")
    }
}

// 8. Resizeable Thread Pool
class ResizeableThreadPool {

    private var threads: [Thread] = []
    private var taskQueue: [() -> Void] = []
    private let lock = NSLock()
    private let condition = NSCondition()
    private var isRunning = true
    private var targetSize: Int

    init(initialSize: Int) {
        targetSize = initialSize
        resize(to: initialSize)
    }

    func resize(to newSize: Int) {
        lock.lock()
        targetSize = newSize
        lock.unlock()

        adjustThreads()
    }

    func submit(_ task: @escaping () -> Void) {
        lock.lock()
        taskQueue.append(task)
        lock.unlock()
        condition.signal()

        adjustThreads()
    }

    private func adjustThreads() {
        lock.lock()
        let currentCount = threads.count
        let needed = targetSize - currentCount
        lock.unlock()

        if needed > 0 {
            // Add threads
            for _ in 0..<needed {
                let thread = Thread { [weak self] in
                    self?.worker()
                }
                lock.lock()
                threads.append(thread)
                lock.unlock()
                thread.start()
            }
        } else if needed < 0 && currentCount > 0 {
            // Signal excess threads to exit (simplified)
        }
    }

    private func worker() {
        while true {
            lock.lock()
            while taskQueue.isEmpty {
                lock.unlock()

                condition.lock()
                condition.wait()
                condition.unlock()

                lock.lock()
                if !isRunning {
                    lock.unlock()
                    return
                }
            }

            let task = taskQueue.removeFirst()
            lock.unlock()

            task()
        }
    }

    static func resizeExample() {
        print("\n--- Resizeable Pool ---")

        let pool = ResizeableThreadPool(initialSize: 2)

        print("Initial size: 2")
        for i in 1...3 {
            pool.submit {
                print("Task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        Thread.sleep(forTimeInterval: 0.2)

        print("Resizing to 5")
        pool.resize(to: 5)

        for i in 4...8 {
            pool.submit {
                print("Task \(i)")
                Thread.sleep(forTimeInterval: 0.1)
            }
        }

        Thread.sleep(forTimeInterval(0.6))
        print("Resizeable pool demo completed")
    }
}

// Main demonstration
func demonstrateThreadPool() {
    print("=== macOS Swift Thread Pool Examples ===")

    // 1. OperationQueue Pool
    OperationQueuePool.basicExample()

    // 2. DispatchQueue Pool
    DispatchQueuePool.basicExample()

    // 3. Custom Pool
    ThreadPool.basicExample()

    // 4. Future/Promise Pool
    FutureThreadPool.futureExample()

    // 5. Priority Pool
    PriorityThreadPool.priorityExample()

    // 6. Work Stealing Pool
    WorkStealingPool.workStealingExample()

    // 7. Resizeable Pool
    ResizeableThreadPool.resizeExample()

    // 8. Modern Task Groups (if available)
    if #available(macOS 12.0, *) {
        Task {
            await ModernTaskGroup.taskGroupExample()
            await ModernTaskGroup.parallelMapExample()
            await ModernTaskGroup.dataProcessingExample()
        }
    }

    print("\n=== All Thread Pool Examples Completed ===")
}

// Run demonstration
demonstrateThreadPool()