C ++ Programlama Dili: Std :: Yürütme ile Rekabet
Bu yazı için bir plan değişikliği var. Orijinal planım, ana dilden sonra C ++ 26 kitapçısını sunmaktı. Ancak, kütüphanenin uygulama durumu yeterince eksiksiz değildir.
Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.
Bu yüzden yarışmaya karar verdim std::execution devam etmek için. Bir derleyici bunları uyguladığı anda C ++ 26'nın kalan özelliklerini sunacağım.
Aufbau von std::execution
std::execution Üç temel soyutlama vardır: zamanlayıcı, verici ve alıcı ve ayrıca bir dizi uyarlanabilir asenkron algoritma. Sunumum std::execution P2300R10 teklifine dayanmaktadır.
İlk deneyler
İlk deneylerim için stdexec kullandım. NVIDIA referansının uygulanması, teklifin sekizinci revizyonuna dayanmaktadır. Bu deneyin amacı GitHub'da bulunabilir:
#include <stdexec/execution.hpp>
#include <exec/static_thread_pool.hpp>
int main()
{
// Declare a pool of 3 worker threads:
exec::static_thread_pool pool(3);
// Get a handle to the thread pool:
auto sched = pool.get_scheduler();
// Describe some work:
// Creates 3 sender pipelines that are executed concurrently by passing to `when_all`
// Each sender is scheduled on `sched` using `on` and starts with `just
` that creates a
// Sender that just forwards `n` to the next sender.
// After `just
`, we chain `then(fun)` which invokes `fun` using the value provided from `just()`
// Note: No work actually happens here. Everything is lazy and `work` is just an object that statically
// represents the work to later be executed
auto fun = [](int i) { return i*i; };
auto work = stdexec::when_all(
stdexec::starts_on(sched, stdexec::just(0) | stdexec::then(fun)),
stdexec::starts_on(sched, stdexec::just(1) | stdexec::then(fun)),
stdexec::starts_on(sched, stdexec::just(2) | stdexec::then(fun))
);
// Launch the work and wait for the result
auto [i, j, k] = stdexec::sync_wait(std::move(work)).value();
// Print the results:
std:
rintf("%d %d %dn", i, j, k);
}
Bu programı Revizyon 10'un sözdizimine dönüştüreceğim. Program, istenen müdahalenin entegrasyonu ile başlıyor:exec/static_thread_pool.hpp> Bir iplik havuzunun oluşturulması için,stdexec/execution.hpp> Yürütme ile ilgili hizmetler için. İçinde main-Bilat olur static_thread_pool pool Sekiz iş parçacığı ile oluşturuldu. İplik havuzu aktiviteleri aynı anda gerçekleştirir. İplik havuzunun get_scaduler üye işlevi bir zamanlayıcı nesne tarafından çağrılır sched Almak için. Zamanlayıcı, iş parçacığı havuzundaki faaliyetleri planlıyor.
Lambda işlevi fun Bir bütün alır i girdi olarak ve karanıza verir (i * i) Geriye doğru. Bu lambda aşağıdaki faaliyetlerde giriş değerlerine uygulanır. İşlev stdexec::when_all Birkaç ikincil saniye bekleyen bir görev oluşturun. Her alt görev işlevle stdexec::starts_on Belirtilen zamanlayıcı üzerindeki etkinliği yarattı sched Bitki. İşlev stdexec::just Tek bir değer (0, 1 veya 2) ve işlev oluşturan bir etkinlik oluşturur stdexec::then alışkın fun-Lembonda bu değere uygulanacak. Ortaya çıkan görev nesnesi bunu yapacak work isminde.
İşlev stdexec::sync_wait Daha sonra etkinliğin tamamlanması için senkronize beklemeye çağırılır. İşlev std::move Görev transferlerinin mülkiyeti work İLE sync_wait. . value-Üyenin işlevi sonucudur. sync_wait İkincil faaliyetler tarafından üretilen değerleri elde etmeyi hatırladı. Bu değerler değişkenlerde i, Cemaat k Dağınık.
Son olarak, program değerlerini sağlar i, j VE k ile std:
rintf konsolda. Bu değerler 0, 1 veya 2 karelerini temsil eder.
Aşağıdaki ekran görüntüsü, programın Explorer derleyicisinde yürütülmesini göstermektedir:
Bu makalenin başında, std :: yürütmenin üç temel soyutlamaya sahip olduğunu yazdım: zamanlayıcı, verici ve alıcı ve bir dizi uyarlanabilir asenkron algoritma.
Yürütme Kaynakları
Bu girişten sonra, uyarlanabilir asenkron algoritmalar serisine gireceğim ve başka örnekler sunacağım.
(RME)
Bu yazı için bir plan değişikliği var. Orijinal planım, ana dilden sonra C ++ 26 kitapçısını sunmaktı. Ancak, kütüphanenin uygulama durumu yeterince eksiksiz değildir.

Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.
Bu yüzden yarışmaya karar verdim std::execution devam etmek için. Bir derleyici bunları uyguladığı anda C ++ 26'nın kalan özelliklerini sunacağım.

Aufbau von std::execution
std::execution Üç temel soyutlama vardır: zamanlayıcı, verici ve alıcı ve ayrıca bir dizi uyarlanabilir asenkron algoritma. Sunumum std::execution P2300R10 teklifine dayanmaktadır.
İlk deneyler
İlk deneylerim için stdexec kullandım. NVIDIA referansının uygulanması, teklifin sekizinci revizyonuna dayanmaktadır. Bu deneyin amacı GitHub'da bulunabilir:
- P2300'de önerilen tasarımın bir tasarım testini sağlayın.
- Gönderen modelini deneyimlemek isteyen geliştiricilere erken erişim sağlayın.
- P2300 tasarımına katılmak veya katkıda bulunmak isteyenlerle işbirliği yapın (karşılama katkıları!).
#include <stdexec/execution.hpp>
#include <exec/static_thread_pool.hpp>
int main()
{
// Declare a pool of 3 worker threads:
exec::static_thread_pool pool(3);
// Get a handle to the thread pool:
auto sched = pool.get_scheduler();
// Describe some work:
// Creates 3 sender pipelines that are executed concurrently by passing to `when_all`
// Each sender is scheduled on `sched` using `on` and starts with `just
// Sender that just forwards `n` to the next sender.
// After `just
// Note: No work actually happens here. Everything is lazy and `work` is just an object that statically
// represents the work to later be executed
auto fun = [](int i) { return i*i; };
auto work = stdexec::when_all(
stdexec::starts_on(sched, stdexec::just(0) | stdexec::then(fun)),
stdexec::starts_on(sched, stdexec::just(1) | stdexec::then(fun)),
stdexec::starts_on(sched, stdexec::just(2) | stdexec::then(fun))
);
// Launch the work and wait for the result
auto [i, j, k] = stdexec::sync_wait(std::move(work)).value();
// Print the results:
std:
}
Bu programı Revizyon 10'un sözdizimine dönüştüreceğim. Program, istenen müdahalenin entegrasyonu ile başlıyor:exec/static_thread_pool.hpp> Bir iplik havuzunun oluşturulması için,stdexec/execution.hpp> Yürütme ile ilgili hizmetler için. İçinde main-Bilat olur static_thread_pool pool Sekiz iş parçacığı ile oluşturuldu. İplik havuzu aktiviteleri aynı anda gerçekleştirir. İplik havuzunun get_scaduler üye işlevi bir zamanlayıcı nesne tarafından çağrılır sched Almak için. Zamanlayıcı, iş parçacığı havuzundaki faaliyetleri planlıyor.
Lambda işlevi fun Bir bütün alır i girdi olarak ve karanıza verir (i * i) Geriye doğru. Bu lambda aşağıdaki faaliyetlerde giriş değerlerine uygulanır. İşlev stdexec::when_all Birkaç ikincil saniye bekleyen bir görev oluşturun. Her alt görev işlevle stdexec::starts_on Belirtilen zamanlayıcı üzerindeki etkinliği yarattı sched Bitki. İşlev stdexec::just Tek bir değer (0, 1 veya 2) ve işlev oluşturan bir etkinlik oluşturur stdexec::then alışkın fun-Lembonda bu değere uygulanacak. Ortaya çıkan görev nesnesi bunu yapacak work isminde.
İşlev stdexec::sync_wait Daha sonra etkinliğin tamamlanması için senkronize beklemeye çağırılır. İşlev std::move Görev transferlerinin mülkiyeti work İLE sync_wait. . value-Üyenin işlevi sonucudur. sync_wait İkincil faaliyetler tarafından üretilen değerleri elde etmeyi hatırladı. Bu değerler değişkenlerde i, Cemaat k Dağınık.
Son olarak, program değerlerini sağlar i, j VE k ile std:
Aşağıdaki ekran görüntüsü, programın Explorer derleyicisinde yürütülmesini göstermektedir:

Bu makalenin başında, std :: yürütmenin üç temel soyutlamaya sahip olduğunu yazdım: zamanlayıcı, verici ve alıcı ve bir dizi uyarlanabilir asenkron algoritma.
Yürütme Kaynakları
- yürütmenin konumunu temsil edin e
- Koddaki bir temsil gerekli değildir.
- Yürütme kaynağını temsil eder.
- Zamanlayıcı kavramı tek bir vericisi algoritması ile tanımlanır: schedule.
- Algoritma schedule Zamanlayıcı tarafından belirlenen bir yürütme kaynağında gerçekleştirilen bir verici döndürür.
- Bu vericiye bağlı bir alıcı nihayet bu değerleri aldığında bazı değerler gönderin,
- just Bu sözde vericiler fabrikasıdır.
- Üç kanalı destekler: değer, hata, durduruldu.
- Bu, sözde bir vericiler tüketicisidir.
- İşi iletir ve mevcut olanı engeller std::thread Ve çalışmayı tamamladıktan sonra ihraççı tarafından gönderilen değerlerin isteğe bağlı bir Tupello'yu döndürür.
Bu girişten sonra, uyarlanabilir asenkron algoritmalar serisine gireceğim ve başka örnekler sunacağım.
(RME)