C ++ 11 concurrency and multithreading summary (a) - the thread concept, creation and mass participation

table of Contents

(B) the exclusive mutex -mutex, lock_guardy with other mutex
(three) unique_lock replace lock_guardy
(d) Singleton (Singleton) thread safety issues under
(e) window critical region
(six) condition_variable
(seven) std :: async asynchronous tasks :: Future std <>
(eight) packaged_task <> and Promise <>
(IX) atomic atomic <> Introduction

(1) Basic Concepts
  1. Concurrent: a program simultaneously perform multiple tasks program.
  2. Process: The executable program is run, it creates a process.
  3. Thread: code execution path, each process has a main thread, and unique, produced along with the process, the end, not better, each thread requires a separate stack space, switching between threads need to save Qieyao many middle of the state, reduce excessive running time switching program, it is best not to over two hundred.
(2) creates a thread

1. Create a thread using the thread
2. created using join, i.e. merges with the main thread
3. Create detacn after use, i.e., separate from the main thread, may lead to memory problems
4.joinable whether join, returns a Boolean value
5. Create a thread class (overloaded operators)
6.lamda expression to create threads


join () function, so that the main thread waits for the child thread execution is completed, the equivalent of obstruction, join finished, join () behind the main thread will continue. This can effectively prevent the main program has stopped running, and the subroutine is not the end of the run, I had to interrupt subroutine.
detach () function, so that the main thread and the child thread executed separately alone can not control, control and management of the sub-libraries run by the c ++ thread, the end of the run is the library released by the c ++ run time. But when the end of the main thread, the child thread will end immediately interrupted.

For details, see block 1

(3) threads of mass participation

1. Incoming char * detach the main function of executing the possible release of memory exception is generated, and must be added const
the above solution may be used configured 2. temporary objects string ( "") pass, if the incoming values in the thread generate constructors, but the main program is over the release
function parameters 3. thread the call need to add & otherwise called three times constructor
4. the preceding call will generate the constructor and copy constructor
5.std :: this_thread :: get_id () available the current process ID
6. The definitions may be used to modify mutable const variable content
7.std :: ref () can not produce copies of the incoming reference configuration may also be used &
8. The internal function call type and parameter passing
9. similar needs smart pointer passed by reference using std :: move ()


Note: when using detach function, do not use the "reference" pay attention to sub-way between threads and the main thread to pass parameters, otherwise one end of the first release of the variables will lead to another thread appears bug.

For details, see block 2

  • Block 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;
	}
}

- block 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;
}


Released nine original articles · won praise 9 · views 2948

Guess you like

Origin blog.csdn.net/Rice__/article/details/105045007