8. とある
“ Note: If this policy is specified together with other policies, such as
when using a policy value of launch::async |launch::deferred,
implementations should defer invocation or the selection of the policy
when no more concurrency can be effectively exploited.
実装依存!!
とはいえ [futures.async] の note に
> 実⾏行ポリシーを launch::async |launch::deferred と指定したときに
は, 並列性を効果的に利⽤用できない場合,どちらのポリシーに従うか
を決めるのを遅延するか,task の実⾏行を遅延する(deferred を選択す
る)べき
というところ
並列性が⼗十分に取れるときの動きは書かれていない(未規定??)
10. にあるように,
同期/⾮非同期的に動くかを library の実装が決めてくれる
Bartos Mileski ⽒氏のblog
default policydefault policy の良さの良さ
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
中⽌止
さらに,resource のこういう error ⾒見なくてよくな
る
11. defaultdefault ,困ります,困ります(>_<)(>_<)
auto fut = srd::async( f ); // use default policy
s, t, u という名前に次のようにスレッドを束縛する
s f が実⾏行されるスレッド
t async が呼ばれるスレッド
u get/wait を呼ぶスレッド
例えば次みたいな code を考えると...
12. void f() {
std::cout << "s: " << std::this_thread::get_id() << std::endl; // s
}
std::future< void > g() {
std::cout << "t: " << std::this_thread::get_id() << std::endl; // t
auto fut = std::async( f );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return fut;
}
int main() {
std::cout << "u:" << std::this_thread::get_id() << std::endl; // u
std::async( g ).get().get();
return 0;
}
http://melpon.org/wandbox/permlink/a7oHldjWHTEGA1Yq
VisualStudio2015 で build した結果
あれ,あれ,ss とと tt が⼀一致しているが⼀一致している!!(!!(環境でまちまち環境でまちまち))
13. defaultdefault ,困ります,困ります(>_<)(>_<)
s != t かわからない (∵ deferred になるかもしれない
s != u かわからない
そもそもget/wait されないかもしれない
s f が実⾏行されるスレッド
t async が呼ばれるスレッド
u get/wait を呼ぶスレッド
*再掲
14. defaultdefault ,困ります,困ります(>_<)(>_<)
thread-local storage(TLS) を使ってると問題出る
thread_local int i = 0;
void fun(int left, int right ) {
if (left < right-1) {
auto f1 = std::async( fun, left, (left + right) / 2);
auto f2 = std::async( fun, (left + right)/2, right);
f1.wait();
f2.wait();
}
else {
++i;
}
}
int main() {
fun(0, 10);
std::cout << i << std::endl;
}
どのスレッドで fun が呼ばれるかで結果が変わる
http://melpon.org/wandbox/permlink/lcd7FOlnXfsUBH7T
15. defaultdefault ,困ります,困ります(>_<)(>_<)
次の code を考える
void f () { std::this_thread::sleep( 1s ); // std::chrono::seconds(1)
auto fut = std::async(f);
while (fut.wait_for(100ms) // std::chrono::milliseconds(1)
!=
std::future_status::ready) {
/* something */
}