SORU
12 HAZİRAN 2012, Salı


Std::söz mü?

Düz ileri olan yeni standart kütüphane 15*, std::async *std::future bileşenleri (this answer bakın, örneğin, oldukça aşina değilim.

Ancak, ne işe yaradığını ve en iyi kullanılan std::promise ne olduğunu kavramak mümkün değil. Sınıfının ötesinde bir sürü bilgi içeriyor kendisi değil standart belge sinopsis de just::thread yapar.

Birisi bir std::promise ihtiyaç duyulan ve en deyimsel çözüm olduğu durumda, kısa, kısa ve öz bir örnek verebilir mi?

CEVAP
8 EYLÜL 2012, CUMARTESİ


Durumu biraz daha iyi şimdi (hiç de küçük bir miktar cevaplara buradan çıkmalıyız!), anlıyorum biraz okumak benim de eklerim diye düşündüm.


C 11 ile ilgili olsa da, iki ayrı kavram vardır: zaman Uyumsuz bir hesaplama (başka bir yerde denilen bir fonksiyon), ve eş zamanlı yürütmeiplikiş yaptığı bir şey aynı anda). İkisi biraz dik kavramlardır. Zaman uyumsuz bir hesaplama iş parçacığı yürütme içeriği ise sadece fonksiyonel­lerine Ara farklı bir lezzet. Konuları kendi başlarına yararlı, ama pur&utangaç;bu tartışma poz için, bir uygulama ayrıntı onları tedavi edeceğim.


Zaman uyumsuz hesaplama için soyutlama bir hiyerarşi vardır. Örnek aşkına, bir argüman alır bir işlevi var varsayalım:

int foo(double, char, bool);

Öncelikle şablon var yazın gelecekteki değeri T temsil std::future<T>,. Val­ue sonucu İçin Üye işlevi etkin bekle program eşitler ve utangaç olan get(),; ıng ile alınabilir. Alternatif olarak, bir gelecek ya da sonucu zaten mevcut olup olmadığını yoklamak için kullanılabilecek wait_for() destekler. Vadeli işlem zaman uyumsuz-damla düşünce re&; yer utangaç ve sıradan dönüş türleri için ment utangaç. Bizim örneğin fonksiyon std::future<int> bekliyoruz.

Şimdi, bu hiyerarşide en yüksek en düşük seviye:

  1. std::async: en kullanışlı ve düz ileri bir şekilde gerçekleştirmek için bir zaman uyumsuz com­pu­ta­ması) async işlev şablonu döndüren, eşleşen gelecek hemen:

    auto fut = std::async(foo, 1.5, 'x', false);  // is a std::future<int>
    

    Ayrıntılar üzerinde çok az kontrole sahip. Özellikle, bile işlevi exe&utangaç olduğunu bilmiyoruz;cu­aynı anda, seri olarak başka bir kara büyü get() üzerine ya da ted. Ancak, sonuç kolayca ob­gerektiğinde tained

    auto res = fut.get();  // is an int
    
  2. Şimdi nasıl kabul edebilirizuygulamakasync, bir moda bu ama gibi bir şeybizkontrol. Örneğin, bu işlev ayrı bir konu yürütülecek ısrar edebiliriz. Biz zaten std::thread sınıfı yoluyla ayrı bir konu sağlayabilir.

    Soyutlama sonraki alt düzeyde tam olarak bunu yapıyor: std::packaged_task. Bu fonksiyon sarar ve işlevleri için bir gelecek değer, ama Ara­mümkün kendisi nesneyi döndürmek sağlayan bir şablondur ve arayan kullanıcı tarafından yapılabilir. Bu şekilde kurabiliriz:

    std::packaged_task<int(double, char, bool)> tsk(foo);
    
    auto fut = tsk.get_future();    // is a std::future<int>
    

    Gelecek görev aradığımızda hazır hale gelir ve aramayı tamamlar. Bu bir se için ideal bir iştir ve pa utangaç&; oranı iplik utangaç. Biz sadece emin olmak içinhareket ettiriniş parçacığı görev:

    std::thread thr(std::move(tsk), 1.5, 'x', false);
    

    Konu hemen çalışmaya başlar. Biz de detach ya join sonunda kapsam veya zaman (örneğin kullanarak Anthony Williams scoped_thread sarıcı, dürüst olmalı standart kütüphane). std::thread kullanarak ayrıntılarını bizi burada ilgilendirmiyor; sadece ya thr katılmak ayırmak için emin eninde sonunda olacak. Önemli olan işlev çağrısı bitirir zaman, sonuçlar hazır olduğunu

    auto res = fut.get();  // as before
    
  3. Şimdi en alt seviyeye indik: Nasıl kiuygulamakpaketlenmiş görev? Bu std::promise giriyor. Söz bir gelecek ile iletişim kurmak için bir yapı taşıdır. Asıl adım bu

    • İş parçasıyla bir söz verir.

    • İş parçasıyla Sözü Bir Gelecek elde eder.

    • Söz, işlev bağımsız değişkenleri ile birlikte, ayrı bir iş parçacığı içine taşınır.

    • Yeni konu işlevini yürütür ve yerine getirir söz doldurur.

    • Özgün iş parçacığı sonuç alır.

    Örnek olarak, burada bizim çok"": . paketlenmiş görevi kendi

    template <typename> class my_task;
    
    template <typename R, typename ...Args>
    class my_task<R(Args...)>
    {
        std::function<R(Args...)> fn;
        std::promise<R> pr;             // the promise of the result
    public:
        template <typename ...Ts>
        explicit my_task(Ts &&... ts) : fn(std::forward<Ts>(ts)...) { }
    
        template <typename ...Ts>
        void operator()(Ts &&... ts)
        {
            pr.set_value(fn(std::forward<Ts>(ts)...));  // fulfill the promise
        }
    
        std::future<R> get_future() { return pr.get_future(); }
    
        // disable copy, default move
    };
    

    Bu şablon kullanımı aslında std::packaged_task ile aynı. Tüm görev dokunaklı söz, hareket araya toplayan unutmayın. Daha özel durumlarda, bir de hareket söz nesne açıkça içine yeni konu ve bir işlev bağımsız değişken iplik işlevi, ama bir görev paketi yukarıda görünüyor, daha esnek ve daha az zorlayıcı bir çözüm.


İstisnalar yapmak

Sözler istisnalar yakından ilişkilidir. Bir söz yalnız arayüzü özel durumlar söz üzerinde bir işlem mantıklı değil her durum onun durumu tamamen iletmek için yeterli değildir. Tüm özel durumları tür std::logic_error dan türetilen std::future_error. Öncelikle bazı kısıtlamalar açıklama:

  • Varsayılan yapılandırılmış bir söz etkin değil. Etkin olmayan sözler sonucu ölebilir.

  • Bir söz bir gelecek get_future() yoluyla elde olduğunda etkin hale gelir. Ancak, sadecebirgelecekte elde edilecek!

  • Bir söz ya set_value() ile tatmin olmak ya da yaşam süresi sona ermeden önce set_exception() ile özel bir set varsa onun geleceği tüketilecek ise gerekir. Memnun bir söz sonucu ölebilir, ve get() geleceği üzerinde kullanılabilir hale gelir. Bir istisna ile bir söz gelecek get() çağrısı üzerine depolanan özel durum yükseltir. Eğer bu söz ne değeri, ne de dışında ölürse, gelecek get() çağıran bir "söz" istisna. kırık arttıracak

İşte bu çeşitli istisnai davranışları göstermek için küçük bir test serisi. İlk olarak, koşum:

#include <iostream>
#include <future>
#include <exception>
#include <stdexcept>

int test();

int main()
{
    try
    {
        return test();
    }
    catch (std::future_error const & e)
    {
        std::cout << "Future error: " << e.what() << " / " << e.code() << std::endl;
    }
    catch (std::exception const & e)
    {
        std::cout << "Standard exception: " << e.what() << std::endl;
    }
    catch (...)
    {
        std::cout << "Unknown exception." << std::endl;
    }
}

Şimdi testlere geçelim.

Durum 1: Etkin olmayan söz

int test()
{
    std::promise<int> pr;
    return 0;
}
// fine, no problems

Durum 2: Aktif söz, kullanılmayan

int test()
{
    std::promise<int> pr;
    auto fut = pr.get_future();
    return 0;
}
// fine, no problems; fut.get() would block indefinitely

Durum 3: Çok fazla vadeli

int test()
{
    std::promise<int> pr;
    auto fut1 = pr.get_future();
    auto fut2 = pr.get_future();  //   Error: "Future already retrieved"
    return 0;
}

Durum 4: Tatmin vaadi

int test()
{
    std::promise<int> pr;
    auto fut = pr.get_future();

    {
        std::promise<int> pr2(std::move(pr));
        pr2.set_value(10);
    }

    return fut.get();
}
// Fine, returns "10".

Vaka 5: Çok fazla memnuniyet

int test()
{
    std::promise<int> pr;
    auto fut = pr.get_future();

    {
        std::promise<int> pr2(std::move(pr));
        pr2.set_value(10);
        pr2.set_value(10);  // Error: "Promise already satisfied"
    }

    return fut.get();
}

Aynı durum, eğer biri varsa atılıryaset_value set_exception.

Vaka 6: İstisna

int test()
{
    std::promise<int> pr;
    auto fut = pr.get_future();

    {
        std::promise<int> pr2(std::move(pr));
        pr2.set_exception(std::make_exception_ptr(std::runtime_error("Booboo")));
    }

    return fut.get();
}
// throws the runtime_error exception

Vaka 7: Kırık söz

int test()
{
    std::promise<int> pr;
    auto fut = pr.get_future();

    {
        std::promise<int> pr2(std::move(pr));
    }   // Error: "broken promise"

    return fut.get();
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Glyn Dewis

    Glyn Dewis

    25 AĞUSTOS 2007
  • max2sims2

    max2sims2

    19 Kasım 2008
  • Yo Mama

    Yo Mama

    18 EYLÜL 2005

İLGİLİ SORU / CEVAPLAR