Iya. Menggunakan antrian serial memastikan eksekusi serial tugas. Satu-satunya perbedaan adalah bahwa dispatch_synchanya kembali setelah blok selesai sedangkan dispatch_asynckembali setelah ditambahkan ke antrian dan mungkin tidak selesai.
Catatan: Untuk kode pertama, tidak akan dicetak 1324. Karena printf("3")dikirim setelahprintf("2") dieksekusi. Dan tugas hanya dapat dieksekusi setelah dikirim.
Waktu pelaksanaan tugas tidak mengubah apa pun. Kode ini selalu dicetak12
pertanyaan saya adalah mengapa kita tidak melakukannya dengan cara biasa? printf("1");printf("2") ;printf("3") ;printf("4")- dibandingkan dengandispatch_sync
androniennn
@ Androniennn untuk contoh kedua? karena beberapa utas lainnya dapat berjalan dispatch_sync(_serialQueue, ^{ /*change shared data*/ });pada saat yang sama.
Bryan Chen
1
@ asma22 Sangatlah berguna untuk berbagi objek aman non-utas antara beberapa utas / antrian pengiriman. Jika Anda hanya mengakses objek dalam antrian serial, Anda tahu Anda mengaksesnya dengan aman.
Bryan Chen
1
Maksud saya eksekusi serial . Dalam pandangan bahwa semua tugas dieksekusi secara serial berkaitan dengan tugas-tugas lain dalam antrian yang sama. Penyebabnya masih bisa bersamaan salam dengan antrian lainnya. Ini adalah inti dari GCD bahwa tugas dapat dikirim dan dieksekusi bersamaan.
Bryan Chen
19
Perbedaan antara dispatch_syncdan dispatch_asyncsederhana.
Dalam kedua contoh Anda, TASK 1akan selalu dieksekusi sebelumnya TASK 2karena telah dikirim sebelumnya.
dispatch_syncNamun, dalam contoh, Anda tidak akan mengirim TASK 2sampai setelah TASK 1dikirim dan dieksekusi . Ini disebut "pemblokiran" . Kode Anda menunggu (atau "memblokir") sampai tugas dijalankan.
Dalam dispatch_asynccontoh ini, kode Anda tidak akan menunggu eksekusi selesai. Kedua blok akan mengirimkan (dan akan di-enqueued) ke antrian dan sisa kode Anda akan terus dieksekusi pada utas itu. Kemudian di beberapa titik di masa depan, (tergantung pada apa lagi yang telah dikirim ke antrian Anda), Task 1akan mengeksekusi dan kemudian Task 2akan mengeksekusi.
Saya pikir pesanan Anda salah. Contoh pertama adalah asyncyang merupakan versi non-pemblokiran
Bryan Chen
Saya telah mengedit jawaban Anda untuk apa yang saya pikir Anda maksudkan . Jika ini bukan masalahnya, harap ubah dan klarifikasi.
JRG-Pengembang
1
Bagaimana jika Anda memanggil dispatch_sync dan kemudian dispatch_async pada antrian yang sama? (dan sebaliknya)
0xSina
1
Pada antrian serial, kedua tugas masih dieksekusi satu demi satu. Dalam kasus pertama, pemanggil menunggu blok pertama selesai tetapi tidak menunggu blok kedua. Dalam kasus kedua, penelepon tidak menunggu sampai blok pertama selesai, tetapi menunggu blok kedua. Tetapi karena antrian mengeksekusi blok secara berurutan, penelepon secara efektif menunggu keduanya selesai.
gnasher729
1
Blok A juga bisa melakukan dispatch_async pada antriannya sendiri (menambahkan blok selanjutnya yang akan dieksekusi nanti); dispatch_sync pada antrian serial sendiri atau antrian utama akan menemui jalan buntu. Dalam situasi ini, penelepon akan menunggu blok asli selesai, tetapi tidak untuk blok lainnya. Ingat saja: dispatch_sync menempatkan blok di akhir antrian, antrian mengeksekusi kode sampai blok itu selesai, dan kemudian dispatch_sync kembali. dispatch_async baru saja menambahkan blokir di akhir antrian.
gnasher729
5
Itu semua terkait dengan antrian utama. Ada 4 permutasi.
i) Serial queue, dispatch async: Di sini tugas akan dieksekusi satu demi satu, tetapi utas utama (efek pada UI) tidak akan menunggu untuk kembali
ii) Antrian serial, sinkronisasi pengiriman: Di sini tugas akan dieksekusi satu demi satu, tetapi utas utama (efek pada UI) akan menunjukkan keterlambatan
iii) Antrian bersamaan, kirim async: Di sini tugas akan dieksekusi secara paralel dan utas utama (efek pada UI) tidak akan menunggu untuk kembali dan akan lancar.
iv) Antrian bersamaan, pengiriman sinkronisasi: Di sini tugas akan dieksekusi secara paralel, tetapi utas utama (efek pada UI) akan menunjukkan kelambatan
Pilihan Anda untuk antrian serentak atau serial bergantung pada apakah Anda memerlukan output dari tugas sebelumnya untuk tugas berikutnya. Jika Anda bergantung pada tugas sebelumnya, gunakan antrian serial jika tidak, ambil antrian bersamaan.
Dan terakhir ini adalah cara untuk menembus kembali ke utas utama ketika kita selesai dengan bisnis kami:
printf("1");printf("2") ;printf("3") ;printf("4")
- dibandingkan dengandispatch_sync
dispatch_sync(_serialQueue, ^{ /*change shared data*/ });
pada saat yang sama.Perbedaan antara
dispatch_sync
dandispatch_async
sederhana.Dalam kedua contoh Anda,
TASK 1
akan selalu dieksekusi sebelumnyaTASK 2
karena telah dikirim sebelumnya.dispatch_sync
Namun, dalam contoh, Anda tidak akan mengirimTASK 2
sampai setelahTASK 1
dikirim dan dieksekusi . Ini disebut "pemblokiran" . Kode Anda menunggu (atau "memblokir") sampai tugas dijalankan.Dalam
dispatch_async
contoh ini, kode Anda tidak akan menunggu eksekusi selesai. Kedua blok akan mengirimkan (dan akan di-enqueued) ke antrian dan sisa kode Anda akan terus dieksekusi pada utas itu. Kemudian di beberapa titik di masa depan, (tergantung pada apa lagi yang telah dikirim ke antrian Anda),Task 1
akan mengeksekusi dan kemudianTask 2
akan mengeksekusi.sumber
async
yang merupakan versi non-pemblokiranItu semua terkait dengan antrian utama. Ada 4 permutasi.
i) Serial queue, dispatch async: Di sini tugas akan dieksekusi satu demi satu, tetapi utas utama (efek pada UI) tidak akan menunggu untuk kembali
ii) Antrian serial, sinkronisasi pengiriman: Di sini tugas akan dieksekusi satu demi satu, tetapi utas utama (efek pada UI) akan menunjukkan keterlambatan
iii) Antrian bersamaan, kirim async: Di sini tugas akan dieksekusi secara paralel dan utas utama (efek pada UI) tidak akan menunggu untuk kembali dan akan lancar.
iv) Antrian bersamaan, pengiriman sinkronisasi: Di sini tugas akan dieksekusi secara paralel, tetapi utas utama (efek pada UI) akan menunjukkan kelambatan
Pilihan Anda untuk antrian serentak atau serial bergantung pada apakah Anda memerlukan output dari tugas sebelumnya untuk tugas berikutnya. Jika Anda bergantung pada tugas sebelumnya, gunakan antrian serial jika tidak, ambil antrian bersamaan.
Dan terakhir ini adalah cara untuk menembus kembali ke utas utama ketika kita selesai dengan bisnis kami:
sumber