Section 3/161 menit
3. Teori: Cooperative Thread Pool dan Task Scheduling
3. Teori: Cooperative Thread Pool dan Task Scheduling
Cara Kerja Cooperative Thread Pool
Swift Concurrency menggunakan cooperative multitasking — berbeda dari preemptive threading di GCD. Dalam cooperative model:
- Thread tidak di-preempt paksa oleh OS scheduler
- Task hanya berpindah thread saat mencapai suspension point (
await) - Jumlah thread = jumlah CPU core (tidak membengkak seperti GCD)
- Setiap thread punya local queue + shared global queue
swift
CPU Core 1: Thread A
Task 1 ─── await ─── Task 2 ─── await ─── Task 1 (resume)
│
Task 2 bisa lanjut di Core 2
CPU Core 2: Thread B
Task 3 ─── await ─── Task 2 (dilanjutkan dari Core 1)
Ketika await dipanggil:
- Task menyimpan continuation (sisa kode setelah await)
- Thread dibebaskan untuk Task lain
- Ketika async operation selesai, continuation di-schedule ke thread yang tersedia
- Task tidak dijamin resume di thread yang sama — kecuali di actor
Priority dan Priority Inversion
Setiap Task punya priority: .background, .utility, .default, .userInitiated, .userInteractive.
swift
// Task dengan priority eksplisit
Task(priority: .userInitiated) {
await criticalOperation()
}
Task(priority: .background) {
await bulkDataSync()
}
// Child Task mewarisi priority parent
Task { // priority: .default (inherited dari context)
async let a = Task(priority: .userInitiated) { await fetchData() }
// a masih berjalan di .userInitiated meski parent .default
}
Priority Inversion terjadi ketika task high-priority menunggu task low-priority. Swift Concurrency mencegah ini dengan priority escalation: ketika task .userInitiated menunggu task .background, priority task .background di-naikkan sementara.
swift
// Swift otomatis handle priority escalation
actor DataStore {
func processHighPriority() async {
// Task ini: .userInitiated
await processLow() // task di sini: .background → dinaikkan ke .userInitiated sementara
}
func processLow() async {
// Meski dibuat sebagai .background, saat ditunggu .userInitiated,
// prioritynya di-escalate otomatis
}
}
Job dan Executor
Di balik Task, ada konsep Job — unit kerja terkecil yang bisa di-schedule. Setiap await membagi Task menjadi serangkaian Jobs.
Executor adalah objek yang menerima dan menjalankan Jobs:
SerialExecutor: jalankan satu job sekaligus (dipakai actor)- Global cooperative pool executor: default untuk unstructured Tasks
- Main actor executor: dispatch ke main thread
swift
Task ──await──► Job1 ──► Executor (runs on thread) ──► Job2 ──► Executor ──► Job3
(resume ketika await selesai)