🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
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
💻 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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 void 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()