C++多线程

如何创建启动一个线程

std::thread创建一个线程对象,传入线程所需要的的线程函数和参数,线程自动开始执行。

void threadHandle1()
{
	//子线程等待两秒
	std::this_thread::sleep_for(std::chrono::seconds(2));
	cout << "hello thread1" << endl;
}

int main()
{
	//定义了一个线程对象 传入一个线程函数  新线程开始运行
	std::thread t1(threadHandle1);

	//主线程等待子线程结束  主线程继续
	//t1.join();

	//把子线程设置为分离线程  
	t1.detach();

	cout << "main thread" << endl;
	return 0;
}

通过加锁来解决多线程问题

static int count = 100;
std::mutex tex; //互斥锁

void sellTicket(int index)
{
	while (::count > 0)  //count==1  锁+双重判断
	{
		tex.lock();
		if (::count > 0)
		{
			cout << "chuangkou" << index << "卖出" << ::count << endl;
			//cout << ::count << endl;
			::count--;
		}
		tex.unlock();
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
}

int main()
{
	list<std::thread> t;
	for (int i = 0; i < 3; i++)
	{
		t.push_back(std::thread(sellTicket, i));
	}

	for (std::thread &v : t)
	{
		v.join();
	}

	cout << "main thread" << endl;
	return 0;
}

生产者与消费者

以下代码存在如果消费者消费过快,生产者还没有生产出来,会导致queue为-1,存在设计问题。

std::mutex mut;

class Queue
{
public:
	void put(int val)
	{
		lock_guard<std::mutex> guard(mut);
		q.push(val);
		cout << "生产者 生产   " << val << endl;
	}

	int get()
	{
		lock_guard<std::mutex> guard(mut);
		int val = q.front();
		q.pop();
		cout << "消费者 消费: " << val << endl;
		return val;
	}

private:
	queue<int> q;
};

void product(Queue *que)
{
	for (int i = 0; i < 10; i++)
	{
		que->put(i);
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

void consumer(Queue *que)
{
	for (int i = 0; i < 10; i++)
	{
		que->get();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

int main()
{
	Queue que;	//两个线程共享的队列
	std::thread t1(product,&que);
	std::thread t2(consumer,&que);

	t1.join();
	t2.join();
	
	return 0;
}

采用线程间通信后

std::mutex mut;
std::condition_variable cv;  //条件变量  线程间通信

class Queue
{
public:
	void put(int val)
	{
		//lock_guard<std::mutex> guard(mut);
		unique_lock<std::mutex> lck(mut);
		while (!q.empty())
		{
			//通知消费者消费 消费了在接着生产  生产者线程应该进入等待状态 把mut互斥锁释放
			
			cv.wait(lck);		//wait只能是unique lock
			
		}
		q.push(val);
		cv.notify_all(); //通知其他线程去消费
		cout << "生产者 生产   " << val << endl;
	}

	int get()
	{
		//lock_guard<std::mutex> guard(mut);
		unique_lock<std::mutex> lck(mut);
		while (q.empty())
		{
			//等待 释放锁
			
			cv.wait(lck);
		}
		int val = q.front();
		q.pop();
		cv.notify_all(); //通知其他线程去消费
		cout << "消费者 消费: " << val << endl;
		return val;
	}

private:
	queue<int> q;
};

void product(Queue *que)
{
	for (int i = 0; i < 10; i++)
	{
		que->put(i);
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

void consumer(Queue *que)
{
	for (int i = 0; i < 10; i++)
	{
		que->get();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}

再谈unique_lock与lock_guard

lock_guard不能用于拷贝构造和赋值,所以不能用来函数参数传递和返回过程中。只能用于简单的临界区代码互斥操作。

unique_lock能用于简单的临界区代码互斥操作,还能在函数调用的过程中。

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页