C++11多线程(3)

创建、等待多个线程

创建多个线程时,最好使用vector与join()函数结合使用

#include <iostream>
#include <thread>
#include <vector>

using namespace std;

void print()
{
	cout << "hello world" << endl;
}

int main()
{
	vector<thread> threadVec;
	for (int i = 0; i < 10; i++)
	{
		threadVec.push_back(thread(print));
	}
	for (vector<thread>::iterator it = threadVec.begin(); it != threadVec.end(); ++it)
	{
		it->join();
	}
	system("Pause");
	return 0;
}

二、共享数据

1、只读数据

#include <iostream>
#include <thread>
#include <vector>

using namespace std;

vector<int> g_v = { 1, 2, 3 };		//共享数据,只读

void print()
{
	cout << "id为 " << this_thread::get_id() << "的线程 打印g_v的值 " << g_v[0] << g_v[1] << g_v[2] << endl;
}

int main()
{
	vector<thread> threadVec;
	for (int i = 0; i < 10; i++)
	{
		threadVec.push_back(thread(print));
	}
	for (vector<thread>::iterator it = threadVec.begin(); it != threadVec.end(); ++it)
	{
		it->join();
	}
	system("Pause");
	return 0;
}

共享数据是只读的情况下不会出现错误,所有的线程都能够按序打印1,2,3.所以共享数据只是可读数据时不必做特殊处理;

2、有读有写

#include <iostream>
#include <thread>
#include <vector>
#include <list>

using namespace std;


class A
{
public:
	void inMsgRecQueue()
	{
		for (int i = 0; i < 100000; i++)
		{
			cout << "inMsgRecQueue执行" << endl;
			msgRecvQueue.push_back(i);
		}
	}
	void outMsgRecvQueue()
	{
		for (int i = 0; i < 100000; i++)
		{
			if (!msgRecvQueue.empty())
			{
				int command = msgRecvQueue.front();
				msgRecvQueue.pop_front();
			}
			else
			{
				cout << "outMsgRecvQueue()执行,但是为空" << endl;
			}
		}
	}
private:
	list<int> msgRecvQueue;
};

int main()
{
	A a;
	thread myOutThread = thread(&A::outMsgRecvQueue, &a);
	thread myInThread = thread(&A::inMsgRecQueue, &a);
	myInThread.join();
	myOutThread.join();
	system("Pause");
	return 0;
}

程序运行过程中会出现错误,有读有写造成的,所以要进行特殊处理,具体代码如下所示:

#include <iostream>
#include <thread>
#include <vector>
#include <list>
#include <mutex>

using namespace std;


class A
{
public:
	void inMsgRecQueue()
	{
		mutexs.lock();
		for (int i = 0; i < 100000; i++)
		{
			cout << "inMsgRecQueue执行" << endl;
			msgRecvQueue.push_back(i);
		}
		mutexs.unlock();
	}
	void outMsgRecvQueue()
	{
		mutexs.lock();
		for (int i = 0; i < 100000; i++)
		{
			if (!msgRecvQueue.empty())
			{
				int command = msgRecvQueue.front();
				msgRecvQueue.pop_front();
			}
			else
			{
				cout << "outMsgRecvQueue()执行,但是为空" << endl;
			}
		}
		mutexs.unlock();
	}
private:
	list<int> msgRecvQueue;
	mutex mutexs;
};

int main()
{
	A a;
	thread myOutThread = thread(&A::outMsgRecvQueue, &a);
	thread myInThread = thread(&A::inMsgRecQueue, &a);
	myInThread.join();
	myOutThread.join();
	system("Pause");
	return 0;
}

加上互斥量mutex后就可以进行安全访问了,必须包含头文件#include <mutex> 有两个重要的函数lock()和unlock(),对要访问的共享区加锁,解锁。在程序中lock()与unlock()必须成对使用,否则就会出现错误,这样在程序中比较容易发生错误。为了防止这种情况的发生,可以使用lock_guard()来代替之前的lock()与unlock()函数。lock_guard()是一个模板类函数,该函数在创建对象的时候调用lock()函数,在析构对象的时候调用unlock()函数,所以一定要注意该函数的作用域,在适当的范围内加大括号,在作用块的结束点析构对象。具体使用如下:

#include <iostream>
#include <thread>
#include <vector>
#include <list>
#include <mutex>

using namespace std;


class A
{
public:
	void inMsgRecQueue()
	{
		for (int i = 0; i < 100000; i++)
		{
			lock_guard<mutex> guard(mutexs);		//创建,但是一定注意作用域
			cout << "inMsgRecQueue执行" << endl;
			msgRecvQueue.push_back(i);
		}
	}
	void outMsgRecvQueue()
	{
		for (int i = 0; i < 100000; i++)
		{
			lock_guard<mutex> guard(mutexs);
			if (!msgRecvQueue.empty())
			{
				int command = msgRecvQueue.front();
				msgRecvQueue.pop_front();
			}
			else
			{
				cout << "outMsgRecvQueue()执行,但是为空" << endl;
			}
		}
	}
private:
	list<int> msgRecvQueue;
	mutex mutexs;			//互斥量对象
};

int main()
{
	A a;
	thread myOutThread = thread(&A::outMsgRecvQueue, &a);	//创建成员函数线程
	thread myInThread = thread(&A::inMsgRecQueue, &a);		//创建成员函数线程
	myInThread.join();
	myOutThread.join();
	system("Pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u012967763/article/details/82837386