Std::söz mü? | Netgez.com
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

  • ★TheCrono Official Channel★

    ★TheCrono

    3 Mayıs 2014
  • 24 Канал

    24 КанаÐ

    5 ÅžUBAT 2006
  • SerienTrailerMP

    SerienTraile

    7 HAZİRAN 2012

İLGİLİ SORU / CEVAPLAR