C++同時プログラミングのstd::threadの基本的な使い方
一.基本的な使い方
パラメータを渡す際には、threadはパラメータのコピーを使用するため、スケジューラとパラメータタイプがコピー構造をサポートする必要があることに注意してください.スレッド参照値に渡すにはrefライブラリを使用してパッケージする必要があります.また、スレッド実行中に参照されるオブジェクトが常に存在することを保証します.そうしないと、未定義の動作が発生します.二.マルチスレッド転送パラメータ:
三.スレッドのjoinとdetach
注意:
WindowsでもPosixでも、メインスレッドとサブスレッドのデフォルト関係は、サブスレッドの実行が完了したかどうかにかかわらず、メインスレッドの実行が完了して終了すると、すべてのサブスレッドの実行が終了します.この場合、プロセス全体が終了または硬直し、一部のスレッドは実行を終了したがまだ破棄されていない状態を維持し、プロセスはすべてのスレッドが破棄された後に破棄されなければならない.この場合、プロセスは硬直した状態にある.スレッド関数の実行が完了して終了するか、または他の非常に終了すると、スレッドは終了状態に入りますが、スレッドに割り当てられたシステムリソースは必ずしも解放されるとは限りません.システムが再起動するまで、ずっと解放できない可能性があります.終了状態のスレッドは、依然としてスレッドエンティティとしてオペレーティングシステムに存在し、いつ破棄されるかは、スレッドのプロパティに依存します.この場合、プライマリ・スレッドとサブスレッドは通常、次の2つの関係を定義します.
1、合流可能(joinable):この関係で、メインスレッドは明確に待機操作を実行する必要があり、サブスレッドが終了した後、メインスレッドの待機操作が完了し、サブスレッドとメインスレッドが合流した場合、メインスレッドは待機操作後の次の操作を継続する.プライマリ・スレッドは、合流可能なサブスレッドに合流する必要があります.メインスレッドのスレッド関数内部でサブスレッドオブジェクトを呼び出すwait関数実装は、サブスレッドがメインスレッドの前に実行され、終了状態に入ることができても、合流操作を実行する必要があります.そうしないと、システムはスレッドを自発的に破棄することはなく、そのスレッドに割り当てられたシステムリソースは解放されません.
2、相分離(detached):サブスレッドがメインスレッドと合流する必要がないことを示す、すなわち相分離である.この場合、サブスレッドが一旦終了状態に入ると、この方式はオンラインスレッド数が多い場合によく用いられるが、メインスレッドを1つずつサブスレッドの終了を待つか、メインスレッドごとにサブスレッドの終了の待機順序を手配することは困難または不可能である場合がある.したがって,サブスレッドが多い場合にもよく用いられる.
いずれの時点においても、スレッドは結合可能であるか、または分離可能である.結合可能なスレッドは、他のスレッドによってリソースを回収し、殺すことができる.他のスレッドによって回収される前に、スタックなどのメモリリソースは解放されません.逆に、分離されたスレッドは、他のスレッドによって回収または殺すことができず、そのメモリリソースは、その終了時にシステムによって自動的に解放される.join()は簡単な暴力的な方法です.新しいスレッドがjoin()を呼び出すと、新しいスレッドが実行されるまで、メインスレッドは新しいプロセスを待っています(Waits for this thread to die).一方、detach()は、呼び出しスレッドからスレッドを分離し、スレッドが独立して実行できるようにします.分離スレッドは他のスレッドに待たれず、自分で実行が終了すると、スレッドは終了し、すぐにシステムリソースを解放します.しかし、メインプロセスが終了すると、detachから出たサブスレッドでも完了するかどうかにかかわらず強制的に殺される.簡単に言えばmain()関数はスレッドオブジェクトを終了すると析出し,スレッドが実行されなければ爆発する.したがってjoinブロックを呼び出し、スレッドの実行が完了するのを待つ.あるいはdetachでバックグラウンドに置きますが、バックグラウンドに置くと制御できません.このときthreadオブジェクトはスレッド体を代表しません.joinable()=falseです.
四.Lambda式とthread結合
五.スレッド交換
六.スレッド移動
出典:C++11同時std::thread:http://blog.csdn.net/liuker888/article/details/46848905.
#include
#include
using namespace std;
void show(const char str[], const int id)
// void show(const char *str, const int id)
{
cout << " " << id + 1 << " :" << str << endl;
}
int main()
{
thread t1(show, "hello cplusplus!", 0);
t1.join();
thread t2(show, " ,C++!", 1);
t2.join();
thread t3(show, "hello!", 2);
t3.join();
return 0;
}
#include
#include
using namespace std;
void sayHello();
void show();
void method(int &a)//ref
{
a += 5;
cout <int main(int argc, char const *argv[]) {
int a = 0;
thread th1(&method,ref(a));//ref !!
thread th1_move = thread(move(th1));//move constructor,th 1はth 1_に するmove th 1は され、せん に する
th1_move.join();
thread t11 (&sayHello);
t11.join();
cout<<「world」<cout<<「---------」<//スタック
thread t1(show); // による
thread t2(show);
thread t3(show);
//スレッド
thread th[3]{thread(show), thread(show), thread(show)};
// み げ
thread *pt1(new thread(show));
thread *pt2(new thread(show));
thread *pt3(new thread(show));
//スレッドポインタ
thread *pth(new thread[3]{thread(show), thread(show), thread(show)});
return 0;
}
void sayHello()
{
cout<<"hello"<void show()
{
cout << "hello cplusplus!" << endl;
}
パラメータを渡す際には、threadはパラメータのコピーを使用するため、スケジューラとパラメータタイプがコピー構造をサポートする必要があることに注意してください.スレッド参照値に渡すにはrefライブラリを使用してパッケージする必要があります.また、スレッド実行中に参照されるオブジェクトが常に存在することを保証します.そうしないと、未定義の動作が発生します.二.マルチスレッド転送パラメータ:
#include
#include
using namespace std;
void show(const char str[], const int id)
{
cout << " " << id + 1 << " :" << str << endl;
}
int main()
{
thread t1(show, "hello cplusplus!", 0);
t1.join();
thread t2(show, " ,C++!", 1);
t2.join();
thread t3(show, "hello!", 2);
t3.join();
return 0;
}
三.スレッドのjoinとdetach
#include
#include
#include
using namespace std;
void show()
{
cout << "hello cplusplus!" << endl;
}
int main()
{
thread th = thread(show);
th.detach();// , , , 。
//detach , , 。
cout << th.joinable() << endl;
//th.join(); //error
array threads = { thread(show), thread(show), thread(show) };
for (int i = 0; i < 3; i++)
{
cout << threads[i].joinable() << endl;// join
threads[i].join();//
}
return 0;
}
注意:
WindowsでもPosixでも、メインスレッドとサブスレッドのデフォルト関係は、サブスレッドの実行が完了したかどうかにかかわらず、メインスレッドの実行が完了して終了すると、すべてのサブスレッドの実行が終了します.この場合、プロセス全体が終了または硬直し、一部のスレッドは実行を終了したがまだ破棄されていない状態を維持し、プロセスはすべてのスレッドが破棄された後に破棄されなければならない.この場合、プロセスは硬直した状態にある.スレッド関数の実行が完了して終了するか、または他の非常に終了すると、スレッドは終了状態に入りますが、スレッドに割り当てられたシステムリソースは必ずしも解放されるとは限りません.システムが再起動するまで、ずっと解放できない可能性があります.終了状態のスレッドは、依然としてスレッドエンティティとしてオペレーティングシステムに存在し、いつ破棄されるかは、スレッドのプロパティに依存します.この場合、プライマリ・スレッドとサブスレッドは通常、次の2つの関係を定義します.
1、合流可能(joinable):この関係で、メインスレッドは明確に待機操作を実行する必要があり、サブスレッドが終了した後、メインスレッドの待機操作が完了し、サブスレッドとメインスレッドが合流した場合、メインスレッドは待機操作後の次の操作を継続する.プライマリ・スレッドは、合流可能なサブスレッドに合流する必要があります.メインスレッドのスレッド関数内部でサブスレッドオブジェクトを呼び出すwait関数実装は、サブスレッドがメインスレッドの前に実行され、終了状態に入ることができても、合流操作を実行する必要があります.そうしないと、システムはスレッドを自発的に破棄することはなく、そのスレッドに割り当てられたシステムリソースは解放されません.
2、相分離(detached):サブスレッドがメインスレッドと合流する必要がないことを示す、すなわち相分離である.この場合、サブスレッドが一旦終了状態に入ると、この方式はオンラインスレッド数が多い場合によく用いられるが、メインスレッドを1つずつサブスレッドの終了を待つか、メインスレッドごとにサブスレッドの終了の待機順序を手配することは困難または不可能である場合がある.したがって,サブスレッドが多い場合にもよく用いられる.
いずれの時点においても、スレッドは結合可能であるか、または分離可能である.結合可能なスレッドは、他のスレッドによってリソースを回収し、殺すことができる.他のスレッドによって回収される前に、スタックなどのメモリリソースは解放されません.逆に、分離されたスレッドは、他のスレッドによって回収または殺すことができず、そのメモリリソースは、その終了時にシステムによって自動的に解放される.join()は簡単な暴力的な方法です.新しいスレッドがjoin()を呼び出すと、新しいスレッドが実行されるまで、メインスレッドは新しいプロセスを待っています(Waits for this thread to die).一方、detach()は、呼び出しスレッドからスレッドを分離し、スレッドが独立して実行できるようにします.分離スレッドは他のスレッドに待たれず、自分で実行が終了すると、スレッドは終了し、すぐにシステムリソースを解放します.しかし、メインプロセスが終了すると、detachから出たサブスレッドでも完了するかどうかにかかわらず強制的に殺される.簡単に言えばmain()関数はスレッドオブジェクトを終了すると析出し,スレッドが実行されなければ爆発する.したがってjoinブロックを呼び出し、スレッドの実行が完了するのを待つ.あるいはdetachでバックグラウンドに置きますが、バックグラウンドに置くと制御できません.このときthreadオブジェクトはスレッド体を代表しません.joinable()=falseです.
四.Lambda式とthread結合
#include
#include
using namespace std;
int main()
{
auto fun = [](const char *str) {
cout << str << endl; };
thread t1(fun, "hello world!");
t1.join();
thread t2(fun, "hello beijing!");
t2.join();
return 0;
}
五.スレッド交換
#include
#include
using namespace std;
int main()
{
thread t1([]()
{
cout << "thread1" << endl;
});
thread t2([]()
{
cout << "thread2" << endl;
});
cout << "thread1' id is " << t1.get_id() << endl;
cout << "thread2' id is " << t2.get_id() << endl;
cout << "swap after:" << endl;
swap(t1, t2);//
cout << "thread1' id is " << t1.get_id() << endl;
cout << "thread2' id is " << t2.get_id() << endl;
t1.join();
t2.join();
return 0;
}
六.スレッド移動
#include
#include
using namespace std;
int main()
{
thread t1([]()
{
cout << "thread1" << endl;
});
cout << "thread1' id is " << t1.get_id() << endl;
thread t2 = move(t1);
cout << "thread2' id is " << t2.get_id() << endl;
t2.join();
return 0;
}
出典:C++11同時std::thread:http://blog.csdn.net/liuker888/article/details/46848905.