C ++ 11並行処理及びマルチスレッド概要() - スレッドの概念、作成および質量参加

ディレクトリ

(B)の排他的ミューテックス-mutex、他のミューテックスとlock_guardy
lock_guardy置き換えるunique_lockの(3)
の下(D)シングルトン(シングルトン)スレッド安全性の問題を
(e)の窓クリティカル領域
(6)condition_variable
(7)のstd ::非同期タスク非同期::今後のstd <>
(8)packaged_task <>との約束<>
(IX)、原子、原子<>はじめに

(1)基本的な考え方
  1. 同時:プログラムは、同時に複数のタスクプログラムを実行します。
  2. プロセス:実行可能プログラムが実行され、それがプロセスを作成します。
  3. スレッド:コードの実行パス、各プロセスは、プロセスと一緒に生産メインスレッド、および独自のを、持っている、終わりは、ない方が良い、各スレッドは、スレッド間の切り替え、別のスタック領域を必要とQieyaoを保存する必要があります状態の多くの真ん中には、それはない200以上に最善である、過度の実行時間切替プログラムを減らします。
(2)スレッドを作成します

スレッド使用してスレッドを作成1.
メインスレッドで、すなわち合流、参加使用して作成2.
メモリの問題につながる可能性があり、すなわち、使用後detacn作成メインスレッドとは別の3
4.joinableか参加、ブール値を返す
スレッドクラスを作成5. (オーバーロードされた演算子)
スレッドを作成するために6.lamda式


メインスレッドの後ろ)(参加、完成参加するので、障害物の同等の、子スレッドの実行が完了するためにメインスレッドが待機すること、()関数への参加が継続されます。これは、効果的にメインプログラムが実行を停止している、とサブルーチンが実行の終わりではない、私は割り込みサブルーチンに持っていた防ぐことができます。
デタッチ()関数は、そのメインスレッドとサブライブラリーの、制御および管理を制御することはできません別途のみで実行子スレッドがcで++スレッドを実行することを、実行の最後には、C ++実行時によって解放ライブラリです。しかし、時にメインスレッドの終わりには、子スレッドはすぐに中断され終了します。

詳細については、ブロック1を参照してください

(3)質量参加のスレッド

1.着信チャー*生成されるメモリ例外の可能な放出を実行する主な機能を取り外し、そしてCONST追加する必要があり
、2一時オブジェクトの文字列(「」)を通過する構成を用いてもよい上記の溶液であれば、スレッド内の着信値コンストラクタを生成しますが、メインプログラムがリリース上にある
関数のパラメータ3スレッドを追加するには、コールが必要とそうでない場合は3回、コンストラクタが呼び出された
4の前の呼び出しは、コンストラクタを生成してコピーするコンストラクタ
5.std :: this_thread :: GET_ID()利用可能現在のプロセスID
6.定義が変更可能なCONST変数内容変更するために使用することができる
にも使用&ことができる着信基準設定のコピーを生成することができない)7.std :: REFを(
通過内部関数コールタイプおよびパラメータ8
参照によって渡さ9同様のニーズスマートポインタstd ::移動()を使用して


注:切り離し機能を使用する場合、パラメータを渡すために、スレッドとメインスレッド間でサブウェイに「参照」有料の注意を使用していない、それ以外の変数の最初のリリースの一端が別のスレッドにつながることはバグが表示されます。

詳細については、ブロック2を参照してください

  • ブロック1
#include <iostream>
#include<thread>

using namespace std;


//子线程调用函数
void myprint();

class CPrint
{
public:
	CPrint() {};
	~CPrint() {};
	void operator()();		
};

void test1()//类创建线程
{
	CPrint my;
	thread myobj(my);
	myobj.join();
}

void test2()  //使用lambda表达式创建线程
{
	auto my = [] {
		for (auto i = 0; i < 10; i++)
		{
			cout << "mylambda:[" << i << "]" << endl;
		}
	};
	thread myobj(my);
	myobj.detach();
}

int main()
{
	//创建子线程,并开始执行函数
	thread myobj(myprint);

	//汇合,即堵塞
	//主线程等待子线程运行结束后才继续运行主线程,没join主线程提前结束会发生异常

	//if (myobj.joinable())
	//	myobj.join();

	//分离,非堵塞
	//主线程结束了仍执行,互不相关,被c++时库接管并结束后清理
	//detach后不可以再用join ,应用较少
	//若有引用主线程的值,主线程结束后会引发内存问题

	myobj.detach();
	if (myobj.joinable())
		cout << "能加入" << endl;
	else
		cout << "不能加入" << endl;
	for (int i = 0; i < 20; i++)
	{
		cout << "main_" << i << endl;
	}

	test2();
	test1();
	
}


void myprint()
{
	for (int i = 0; i < 20; i++)
	{
		cout << "子线程_" << i << endl;
	}
}


void CPrint::operator()()
{
	for (auto i = 0; i < 10; i++)
	{
		cout << "CPring::(" << i << ")" << endl;
	}
}

- ブロック2
#include <iostream>
#include<thread>

using namespace std;

class CPrint
{
public:
	CPrint(int i) :id(i) { cout << "构造函数"<< this <<" id:" << id << "thread_id = " << this_thread::get_id() << endl; };
	CPrint(const CPrint& obj) { id = obj.id; cout << "拷贝构造 " << this << "id:" << id << "thread_id = " << this_thread::get_id() << endl; };
	~CPrint() { cout << "析构结束~ " << this << " thread_id = " << this_thread::get_id() << endl; };

	mutable int id; //可以在const下改变赋值

	void thread_work(int num) { id = 999; cout << "thread_work() " << this << "num:" << num << "thread_id = " << this_thread::get_id() << endl; }
};

void print(const CPrint& obj) //不加const会报错 除非传ref
{
	obj.id = 0;
	cout << "print() " << &obj << " id:" << obj.id << "thread_id = " << this_thread::get_id() << endl;
}

int main()
{
	CPrint obj1(666);
	thread mythread1(print, ref(obj1)); //构造和拷贝在主函数完成,使用ref则没有拷贝构造

	mythread1.join();
	cout << "main() obj1.id="<< obj1.id <<" thread_id = " << this_thread::get_id() << endl;//id已经改变

	cout << endl << endl;

	CPrint obj2(777);
	thread mythread2(&CPrint::thread_work, obj2,555); //调用类方法,也会产生拷贝构造

	mythread2.detach();
	cout << "main() obj1.id=" << obj2.id << " thread_id = " << this_thread::get_id() << endl; // id不改变

	cout << endl << endl;
}


リリース9件のオリジナルの記事 ウォンの賞賛9 ビュー2948

おすすめ

転載: blog.csdn.net/Rice__/article/details/105045007