macOS Swift 多线程示例
macOS Swift 多线程示例,包括线程创建、使用锁同步和线程池使用
💻 线程创建 swift
🟡 intermediate
⭐⭐⭐
使用 Thread 类和 DispatchQueue 创建和管理线程以执行并发任务
⏱️ 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()
💻 线程同步 swift
🟡 intermediate
⭐⭐⭐⭐
使用锁、信号量、屏障和条件变量同步线程访问
⏱️ 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()
💻 线程池 swift
🔴 complex
⭐⭐⭐⭐⭐
实现线程池模式以高效执行任务和资源管理
⏱️ 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()