記事のディレクトリ
-
創造と破壊RAIIスタイルのスレッドを提供するThreadクラススレッド、。あなたは、コード・セグメントの着信スレッドを実行するスレッド(機能、ラムダ式)とパラメータを作成すると、スレッドデストラクタが自動的にスレッドを破壊します。
-
スレッドオブジェクトをするスレッド、スレッドオブジェクト構築することによって開始するC ++スレッドライブラリのような時間実行コンテキストスレッドが含まれる:等スレッド関数、スレッド・スタック、ステータス及びスレッドIDを開始スレッドは、すべての操作は、すべての中にカプセル化一緒に、そして最終的に達成したスレッドを作成するための基盤となるユニティ_beginthreadex()関数に渡された(注:_beginthreadexは、WindowsのC関数の底にスレッドを作成することです)。
-
std ::新しいスレッドを作成するスレッドが()ラムダ式(とや変数キャプチャなし)、機能(グローバル関数やメンバ関数)を含む任意の呼び出し可能オブジェクトタイプ(パラメータ付きまたはパラメータなし)を、取ることができ、関数オブジェクト。
スレッド開始:スレッドオブジェクトのコンストラクタ
グローバル関数構造によって
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
void threadRoute(int a,int b)
{
cout << "I am a new thread of " << std::this_thread::get_id() << endl;
cout << a + b << endl;
}
int main()
{
int a = 10, b = 20;
cout << "I am the main thread,and my thread id is " << std::this_thread::get_id() << endl;
std::thread t(threadRoute,a,b);//thread对象构造函数指定线程执行函数
t.join();//线程等待,防止出现孤儿线程
system("pause");
}
ラムダ発現構築により、
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
int main()
{
int a = 10, b = 20;
cout << "I am the main thread,and my thread id is " << std::this_thread::get_id() << endl;
std::thread t([=]{
cout << "I am a new thread of " << std::this_thread::get_id() << endl;
cout << a + b << endl;
});
t.join();//线程等待,防止出现孤儿线程
system("pause");
}
関数オブジェクトを構築することで
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
struct funcClass{
void operator()(int a, int b)
{
cout << "ID:" << std::this_thread::get_id() << endl;
cout << a + b << endl;
}
};
int main()
{
funcClass fc;//函数对象构造线程时候,必须先有函数对象,操作符不能是静态的
std::thread t(fc, 10, 20);
t.join();
system("pause");
return 0;
}
メンバーのコンストラクタによって
#include <iostream>
#include <thread>
using namespace std;
struct A
{
static void memberFunc(int a,int b)
{
cout << "hello from class member function :" << this_thread::get_id() << endl;
cout << a + b << endl;
}
};
int main(int argc, char **argv)
{
thread t1(A::memberFunc,10,20);
t1.join();
system("pause");
return 0;
}
スレッドの終了
あなたは、スレッドが終了する前に別のスレッドをデタッチスレッドオブジェクトのメンバ関数を使用し、スレッドを終了するのを待つしたくない場合は、スレッドを作成し、デフォルトの状態が合流可能な状態であり、待つメインスレッドを必要とします。
式に参加:参加します()
()参加:待機中のスレッドを終了するためのイニシアチブをとるだろう。新しいスレッドが終了したとき、()呼び出しプロセスに参加し、参加する()関連付けられたリソースをクリーンアップして、呼び出し元のスレッドに戻り、その後、ダウン続けます。以来スレッドのリソースをクリーンアップするために)(参加、糸と糸のオブジェクトが破壊された関係がない、あなたがターゲットとそうたびにスレッドが一度(参加のみを使用することができます)、あなたが結合可能の呼び出しを()(参加する場合)それは偽のリターンとなります。
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
void threadRoute()
{
cout << "ID:" << std::this_thread::get_id() << endl;
}
int main()
{
cout << "Main ID:" << std::this_thread::get_id() << endl;
std::thread t(threadRoute);//thread对象构造函数指定线程执行函数
cout << t.joinable() << endl;//默认是joinable状态
t.join();//线程等待,防止出现孤儿线程
cout << t.joinable() << endl;//join一次就会把线程资源释放掉,现在已经是false了
system("pause");
}
セパレート:切り離し()
デタッチ:呼び出し元のスレッドがもはや新しいスレッドと対話しないの後に別れたから、新しいスレッドを整理します。あなたとあなたのガールフレンドが解散したように彼女の資源の消費量が(クリーンアップリソース)を支払うことにあなたを必要としません後にしながら、そのあとは、接触(相互作用)がありません。この時点で、合流可能()がfalseを返さなければなりません呼び出します。デーモン(孤立)に別のスレッドスレッドは、Linux上でC ++でライブラリによって引き継がれ、initによって引き継が。
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
void threadRoute()
{
cout << "ID:" << std::this_thread::get_id() << endl;
}
int main()
{
cout << "Main ID:" << std::this_thread::get_id() << endl;
std::thread t(threadRoute);//thread对象构造函数指定线程执行函数
cout << t.joinable() << endl;//默认是joinable状态
t.detach();
cout << t.joinable() << endl;//detach函数会将线程分离,不需要主线程join
system("pause");
}
注:あなたがスレッドオブジェクトが破壊される前にあなたが参加するか、別のスレッドの前にスレッドが、それはオーバーだから、それはおそらくある選択をしなければならない、それがある場合、スレッドは、スレッドオブジェクトが破棄された後にダウンを実行し続けることが分離した後に行きます。
スレッドセーフスレッド
スレッドオブジェクトは、所有権を譲渡することができます
可動オブジェクトがのstd :: unique_ptrをかのstd ::はifstreamのようなスレッド、コピー可能ではない、である。 STDは::移動が何かを移動することはできません、その唯一の機能は右を通じて、左と右の基準値に値を強制するために、我々は可能ですセマンティクスを移動するため、この値は基準値を使用して。static_cast <T &&>(左辺値:達成する観点から、STDは、型変換と実質的に同等移動:: ;) 変換値が残っていることを言及する価値がなく、寿命の変更に関する変換値を有します。左の左辺値を移動::変数のstdの目標値は、すぐにデストラクタを変換することができた場合、それは確かに失望するだろう。
#include<iostream>
#include<thread>
using namespace std;
void some_function();
int main()
{
thread t1(some_function);
thread t2 = move(t1); //采用std::move移动语义将t1的所有权移动到t2,
//此时t2接管运行some_function(),而t1此时没有执行线程和其关联
t1 = thread(some_function); //t1仍然是左值
}
スマートポインタスレッドオブジェクトの管理
私たちは、メインスレッド新しいスレッドを作成した後に、メインスレッドにもちょうど終了する他のスレッドを待っているのではなく、他の事をする必要があるのことを知っています。メインスレッドが異常によって引き起こされる別の関数を呼び出すことができますので、メインスレッドが例外処理に直接参加する機能を欠場する可能性があるため、参加する関数の前に、他のことを行うには、メインスレッド。そのため、スレッド合流可能状態は孤児プロセスになっていないことを確実にするために、あなたはスマートポインタがデストラクタに参加し、オブジェクトへのスマートポインタを通すことができます。
#include<iostream>
#include<thread>
using std::cout;
using std::endl;
void threadRoute()//全局函数
{
cout << "ID:" << std::this_thread::get_id() << endl;
}
class Unique_ptr{
public:
Unique_ptr(std::thread& t)//这里使用引用传参,传递的就是new出来的那一个线程对象
:pt(t){}
~Unique_ptr()
{
if (pt.joinable())
pt.join();
}
Unique_ptr(const Unique_ptr&) = delete;
Unique_ptr operator=(const Unique_ptr&) = delete;
private:
std::thread& pt;
};
void func()
{
cout << "Main ID:" << std::this_thread::get_id() << endl;
std::thread t(threadRoute);
Unique_ptr pth(t);
}//pth对象在此调用析构函数,调用线程join函数
int main()
{
func();
system("pause");
}