Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Grand Central Dispatch (GCD) - Đa luồng trên iOS/macOS

Giới thiệu về Grand Central Dispatch (GCD)

Grand Central Dispatch (GCD) là công nghệ của Apple cho macOS và iOS, kết hợp mở rộng ngôn ngữ C, API và thư viện runtime cho phép lập trình viên xác định các đoạn mã chạy song song. GCD quản lý hầu hết chi tiết về luồng (threading) tự động, tương tự như OpenMP.

Khái niệm cốt lõi

Block (Khối mã)

GCD mở rộng C/C++ với khái niệm block - đơn vị công việc tự chứa. Cú pháp dùng dấu ^ trước cặp ngoặc { }:

{
    ^printf("Đây là một block");
}

Dispatch Queue (Hàng đợi thực thi)

GCD lên lịch thực thi block bằng cách đặt chúng vào dispatch queue. Khi lấy block từ queue, GCD gán nó cho một luồng sẵn có trong thread pool.

Hai loại queue:

LoạiĐặc điểmỨng dụng
Serial QueueFIFO, từng block một, block trước phải xong mới lấy block sauĐảm bảo thứ tự thực thi, tránh race condition
Concurrent QueueFIFO nhưng có thể lấy nhiều block cùng lúc → chạy song songXử lý song song, tối ưu hiệu năng
  • Mỗi process có một **serial queue** riêng gọi là **main queue** (chạy UI).
  • Lập trình viên có thể tạo thêm serial queue cục bộ.
  • Có 3 **concurrent queue** hệ thống theo độ ưu tiên: low, default, high.

Ví dụ sử dụng Concurrent Queue

// Lấy default-priority concurrent queue
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// Gửi block thực thi bất đồng bộ
dispatch_async(queue, ^{
    printf("Block này chạy trên background thread");
});

Swift API hiện đại (Khuyên dùng)

Trong Swift, GCD được bao gói đẹp hơn qua DispatchQueue:

// Chạy trên background queue (concurrent)
DispatchQueue.global(qos: .default).async {
    // Công việc nặng: tải ảnh, parse JSON, tính toán...
    let result = heavyComputation()
    
    // Cập nhật UI trên main queue
    DispatchQueue.main.async {
        self.updateUI(with: result)
    }
}

// QoS (Quality of Service) levels:
// .userInteractive - Ưu tiên cao nhất (UI, animation)
// .userInitiated   - Cao (phản hồi hành động user)
// .utility         - Trung bình (download, import)
// .background      - Thấp (backup, sync)
// .default         - Mặc định

Quản lý Thread Pool

  • GCD sử dụng **POSIX threads** nội bộ.
  • Tự động điều chỉnh số lượng luồng dựa trên nhu cầu ứng dụng và dung lượng hệ thống.
  • Không cần tạo/hủy thread thủ công - giảm overhead và bug threading.

Các pattern phổ biến

1. Dispatch Group - Chờ nhiều task song song hoàn tất

let group = DispatchGroup()

group.enter()
fetchUser { group.leave() }

group.enter()
fetchPosts { group.leave() }

group.notify(queue: .main) {
    // Cả hai đã xong
    self.reloadUI()
}

2. Semaphore - Giới hạn số task chạy đồng thời

let semaphore = DispatchSemaphore(value: 3) // Tối đa 3 task cùng lúc

for url in urls {
    semaphore.wait()
    DispatchQueue.global().async {
        download(url)
        semaphore.signal()
    }
}

3. DispatchWorkItem - Có thể hủy (cancel)

let workItem = DispatchWorkItem {
    print("Thực thi sau 2 giây")
}

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: workItem)

// Hủy nếu cần
// workItem.cancel()

Kết luận

GCD là nền tảng đa luồng mạnh mẽ, an toàn và hiệu quả của Apple. Với Swift hiện đại, hãy sử dụng DispatchQueue, DispatchGroup, DispatchSemaphore, DispatchWorkItem thay vì C API cũ để code rõ ràng, type-safe và dễ bảo trì hơn.