注釈について注釈について
auto f =std::async( std::launch::deferred,
[]{ std::cout << "wait..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0; });
std::shared_future< int > sf = f.share();
auto sf2 = sf;
sf.wait();
std::cout << sf2.get() << std::endl;
sf2 に対して wait/get 呼ぶ前から
sf2 の参照する shared_state は結果を持っている
(shared_state に関しては item38 参照)
7.
defaultdefault とと policypolicy指定指定
std::async( f );
std::async( std::launch::async | std::launch::deferred,
f);
default の実⾏行は bit を async/deferred 両⽅方⽴立てるの
と同じ意味
つまり,次の2つは全く同じ挙動をする
このときの挙動は実装依存
8.
とある
“ Note: Ifthis 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 を選択す
る)べき
というところ
並列性が⼗十分に取れるときの動きは書かれていない(未規定??)
にあるように,
同期/⾮非同期的に動くかを library の実装が決めてくれる
BartosMileski ⽒氏の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 */
}