私はvc2011を使用していますが、std :: async(std :: launch :: async、...)は少しバグがあります(新しいスレッドを生成せずに並行して実行する場合がありますが、代わりにスレッドを再利用しますタスクを次々に実行します)。高価なネットワーク通話をしているときは、これは遅すぎます。だから私は自分の非同期関数を書くと思いました。私は立ち往生していますが、std :: promiseはどこに住むべきですか?1)スレッド関数、2)非同期関数、または3)呼び出し元関数。
コード:
#include <future>
#include <thread>
#include <iostream>
#include <string>
#include <vector>
std::string thFun() {
throw std::exception("bang!");
return "val";
}
std::future<std::string> myasync(std::promise<std::string>& prms) {
//std::future<std::string> myasync() {
//std::promise<std::string> prms; //needs to outlive thread. How?
std::future<std::string> fut = prms.get_future();
std::thread th([&](){
//std::promise<std::string> prms; //need to return a future before...
try {
std::string val = thFun();
prms.set_value(val);
} catch(...) {
prms.set_exception(std::current_exception());
}
});
th.detach();
return fut;
}
int main() {
std::promise<std::string> prms; //I really want the promise hidden iway in the myasync func and not live here in caller code but the promise needs to outlive myasync and live as long as the thread. How do I do this?
auto fut = myasync(prms);
//auto fut = myasync(); //Exception: future already retrieved
try {
auto res = fut.get();
std::cout << "Result: " << res << std::endl;
} catch(const std::exception& exc) {
std::cout << "Exception: " << exc.what() << std::endl;
}
}
std :: promiseが非同期関数よりも長生きする必要がある(そしてスレッドが存続する限り存続する)必要があるという事実を乗り越えることができないようです。そのため、promiseは非同期関数のローカル変数として存続できません。ただし、呼び出し元は先物について知っているだけでよいため、std::promiseは呼び出し元のコードにも存在しないはずです。そして、非同期がスレッド関数を呼び出す前にfutureを返す必要があるため、promiseをスレッド関数で有効にする方法がわかりません。私はこれに頭を悩ませています。
誰かアイデアがありますか?
編集:トップコメントが少し誤解されているので、ここでこれを強調しています。std :: asycnのデフォルトは遅延モードであることが許可されていますが、std :: launch :: asyncの起動ポリシーが明示的に設定されている場合、スレッドが生成されて一度に実行されるかのように動作する必要があります(enの文言を参照) .cppreference.com / w / cpp / thread / async)。これがvs20011で見られる動作ではない1つのケースについては、pastebin.com/5dWCjjNYの例を参照してください。このソリューションはうまく機能し、実際のアプリケーションを10倍高速化しました。
編集2:MSがバグを修正しました。詳細はこちら:https ://connect.microsoft.com/VisualStudio/feedback/details/735731/std-async-std-launch-async-does-not-behave-as-std-thread