C++26 Ditetapkan Memasukkan Runtime Async Lalai dan Jenis Task, Mencetuskan Perdebatan Mengenai Pendekatan Penstandardan

Pasukan Komuniti BigGo
C++26 Ditetapkan Memasukkan Runtime Async Lalai dan Jenis Task, Mencetuskan Perdebatan Mengenai Pendekatan Penstandardan

Coroutine C++ telah lama dikenali kerana fleksibiliti dan kerumitannya, memerlukan pembangun untuk melaksanakan jenis task dan rangka kerja pelaksanaan mereka sendiri. Walau bagaimanapun, landskap ini akan berubah dengan ketara dengan C++26, yang akan memperkenalkan runtime async lalai melalui std::execution, membawa keseronokan dan kontroversi kepada komuniti C++.

Komponen Runtime Lalai Yang Akan Datang dalam C++26

Standard C++26 yang akan datang akan memasukkan tiga komponen utama yang mencerminkan fungsi yang terdapat dalam sistem async bahasa lain. Pertama, jenis task coroutine lalai akan menghapuskan keperluan untuk pembangun mencipta implementasi Task mereka sendiri dari awal. Kedua, executor lalai akan mengendalikan penjadualan dan pelaksanaan operasi async. Ketiga, keupayaan untuk spawn task yang serupa dengan Tokio dalam Rust akan menyediakan corak yang biasa untuk pengaturcaraan serentak.

Penambahan ini mewakili peralihan yang ketara daripada pendekatan tradisional C++ yang menyediakan blok binaan peringkat rendah dan bukannya penyelesaian lengkap. Rangka kerja std::execution bertujuan untuk memberikan pembangun sistem async yang sedia digunakan sambil mengekalkan fleksibiliti ciri bahasa tersebut.

Komponen C++26 std::execution

Komponen Tujuan Perbandingan
Jenis tugas coroutine lalai Menghapuskan keperluan untuk pelaksanaan Task tersuai Serupa dengan jenis Task terbina dalam C
Pelaksana lalai Mengendalikan penjadualan dan pelaksanaan operasi async Setanding dengan runtime async dalam bahasa lain
Keupayaan spawning tugas Membolehkan penciptaan tugas serentak Serupa dengan fungsi spawn Tokio dalam Rust

Komuniti Berpecah Mengenai Falsafah Penstandardan

Keputusan untuk memasukkan runtime async lalai telah membahagikan komuniti C++ mengikut garis falsafah. Penyokong berhujah bahawa mempunyai kedua-dua spesifikasi coroutine yang fleksibel untuk pengguna berkuasa dan implementasi lalai untuk kes penggunaan biasa menawarkan yang terbaik dari kedua-dua dunia. Pendekatan ini boleh menurunkan halangan kemasukan untuk pengaturcaraan async dalam C++ dan mengurangkan pemecahan yang wujud pada masa ini merentasi perpustakaan coroutine yang berbeza.

Pengkritik menunjuk kepada pendekatan Rust yang berbeza sebagai kisah amaran. Rust dengan sengaja memilih untuk tidak memasukkan runtime async lalai dalam perpustakaan standardnya, membenarkan ekosistem membangunkan alternatif seperti Embassy untuk sistem terbenam dan menghalang API daripada dibekukan ke dalam reka bentuk yang berpotensi tidak optimum.

Ia mungkin benar-benar boleh berlaku bahawa orang ramai menemui gaya async baharu yang berfungsi lebih baik daripada std::execution.

Kebimbangan tertumpu pada sama ada menstandardkan pendekatan tertentu terlalu awal mungkin menghalang inovasi dalam corak pengaturcaraan async yang belum ditemui lagi.

Keluk Pembelajaran Kekal Curam

Walaupun terdapat penambahbaikan yang akan datang, coroutine C++ terus memberikan cabaran pembelajaran yang ketara. Sistem semasa memerlukan pemahaman pelbagai konsep yang saling berkaitan termasuk jenis promise, awaiter, awaitable, dan pelbagai titik penyesuaian. Sumber pendidikan seperti siri coroutine komprehensif Raymond Chen telah menjadi bacaan penting, tetapi kerumitan kekal menakutkan bagi ramai pembangun.

Tatabahasa dan terminologi sekitar coroutine C++ memerlukan kajian yang teliti, dengan konsep yang memerlukan definisi tepat dan contoh yang luas untuk difahami dengan betul. Kerumitan ini berpunca daripada pendekatan bahasa yang menyediakan fleksibiliti maksimum melalui transformasi pengkompil dan titik penyesuaian, dan bukannya abstraksi yang lebih mudah.

Titik Penyesuaian Utama dalam C++ Coroutines

  • promise_type: Mentakrifkan tingkah laku coroutine untuk operasi panggilan, pemulangan, dan pemusnahan
  • initial_suspend: Tingkah laku sejurus selepas coroutine dipanggil
  • final_suspend: Tingkah laku sejurus sebelum hayat coroutine berakhir
  • await_transform: Mengubah ungkapan dalam pernyataan co_await menjadi awaitables
  • awaiter objects: Mengendalikan operasi suspend dan resume dengan kaedah await_suspend dan await_resume

Aplikasi Praktikal Menunjukkan Potensi

Penggunaan dunia sebenar coroutine C++ menunjukkan nilai mereka walaupun terdapat keluk pembelajaran. Pembangun melaporkan penambahbaikan yang ketara apabila menggantikan kod rangkaian berasaskan callback dengan coroutine, terutamanya dalam senario yang melibatkan tindakan berulang, pengendalian ralat, dan pengurusan jangka hayat data. Keupayaan untuk menulis kod deklaratif dan bukannya mesin keadaan yang kompleks menarik minat ramai pengaturcara yang berurusan dengan protokol rangkaian dan pengendalian mesej.

Penggantian mesin keadaan mewakili satu lagi kes penggunaan yang menarik, di mana coroutine boleh menghapuskan keperluan untuk enum keadaan eksplisit dan penyata switch memihak kepada aliran kawalan yang lebih semula jadi. Ini terbukti sangat berharga dalam pengaturcaraan rangkaian di mana protokol sering memerlukan beberapa langkah rundingan sebelum pemindahan data sebenar bermula.

Pengenalan komponen async lalai dalam C++26 mungkin mempercepatkan penggunaan dengan mengurangkan beban implementasi awal, walaupun kerumitan asas model coroutine berkemungkinan akan kekal sebagai faktor dalam landskap pengaturcaraan async bahasa tersebut.

Rujukan: A Mental Model for C++ Coroutine