1.C++多线程加锁代码-Windows平台

1.多线程加锁代码---为神经网络中的全连接做准备工作,练手

#include <iostream>
#include <thread>
#include <string>
#include <mutex>//互斥锁
/*
1.Mutex 系列类(四种)(https://www.cnblogs.com/haippy/p/3237213.html)
	std::mutex,最基本的 Mutex 类。
	std::recursive_mutex,递归 Mutex 类。
	std::time_mutex,定时 Mutex 类。
	std::recursive_timed_mutex,定时递归 Mutex 类
2.volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,
    且要求每次直接读值。
3.std::mutex 的成员函数
	构造函数,std::mutex不允许拷贝构造,也不允许 move 拷贝,最初产生的 mutex 对象是处于 unlocked 状态的。

	lock(),调用线程将锁住该互斥量。线程调用该函数会发生下面 3 种情况:
		(1). 如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁。
		(2). 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住。
		(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

	unlock(), 解锁,释放对互斥量的所有权。

	try_lock(),尝试锁住互斥量,如果互斥量被其他线程占有,则当前线程也不会被阻塞。线程调用该函数也会出现下面3 种情况,
		(1). 如果当前互斥量没有被其他线程占有,则该线程锁住互斥量,直到该线程调用 unlock 释放互斥量。
		(2). 如果当前互斥量被其他线程锁住,则当前调用线程返回 false,而并不会被阻塞掉。
		(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。
4.std是一个命名空间(namespace),‘::’是作用域运算符,cout是std空间中的一个函数名。使用cout时,必须有使用std命名空间的说明,有两种说明方式。

	方式一:每次使用时对cout说明:       
			std::cout << "Input two numbers:";
	方式二:在主函数前说明一下,后面就可以直接使用cout:
			using namespace std;
			cout << "Input two numbers:";
5.td::this_thread::yield: 当前线程放弃执行,操作系统调度另一线程继续执行。即当前线程将未使用完的“CPU时间片”让给其他线程使用,等其他线程使用完后再与其他线程一起竞争"CPU"。
  std::this_thread::sleep_for: 表示当前线程休眠一段时间,休眠期间不与其他线程竞争CPU,根据线程需求,等待若干时间。

6.
*/
// 车票总数是100张
volatile int tickets = 100;//
// 全局的互斥锁
std::mutex mtx;

// 线程函数
void sellTicketTask(std::string wndName)
{
	while (tickets > 0)
	{
		// 获取互斥锁资源
		mtx.lock();
		if (tickets > 0)
		{
			std::cout << wndName << " 售卖第" << tickets << "张票" << std::endl;
			tickets--;
		}
		// 释放互斥锁资源
		mtx.unlock();

		// 每卖出一张票,睡眠100ms,让每个窗口都有机会卖票
		std::this_thread::sleep_for(std::chrono::milliseconds(100));//std::this_thread::sleep_for表示当前线程休眠一段时间,休眠期间不与其他线程竞争CPU,根据线程需求,等待若干时间。
	}
}

// 模拟车站窗口卖票,使用C++11 线程互斥锁mutex
int main()
{
	// 创建三个模拟窗口卖票线程
	std::thread t1(sellTicketTask, "车票窗口一");
	std::thread t2(sellTicketTask, "车票窗口二");
	std::thread t3(sellTicketTask, "车票窗口三");

	// 等待三个线程执行完成
	t1.join();
	t2.join();
	t3.join();

	return 0;
}

 

2.自己又写了一个

#include <windows.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <string>

using namespace std;//使用标准命名空间:(https://baike.baidu.com/item/using%20namespace%20std/10360651?fr=aladdin)

//DWORD WINAPI Fun1(LPVOID lpParameter);//LPVOID这个是一个宏定义 表示的是指向空类型的指针

//DWORD WINAPI Fun2(LPVOID lpParameter);
//DWORD WINAPI Fun3(LPVOID lpParameter);

// 全局的互斥锁
std::mutex mtx;

int index = 0;
//int money = 100;
int tickets = 100;   //全局变量tickets用来表示销售的剩余票数
					 //线程1入口函数
					 //DWORD WINAPI Fun1(LPVOID lpParameter)
int Fun1(std::string wndName)
{

	while (TRUE)
	{
		mtx.lock();
		if (tickets > 0)
		{
			cout << "车票窗口一 : " << tickets-- << endl;//表示输出换行的意思,相当于C语言里面的printf("\n");

		}
		else
		{
			break;
		}
		mtx.unlock();
		Sleep(1);

	}
	return 0;
}

//线程2的入口函数
//DWORD WINAPI Fun2(std::string wndName)
int Fun2(std::string wndName)
{
	while (TRUE)
	{
		mtx.lock();
		if (tickets > 0)
		{
			
			cout << "车票窗口二 : " << tickets-- << endl;
		}
		else
		{
			break;
		}
		mtx.unlock();
		Sleep(1);
	}
	return 0;
}
//DWORD WINAPI Fun3(std::string wndName)
int Fun3(std::string wndName)
{
	while (TRUE)
	{
		mtx.lock();
		if (tickets > 0)
		{
			
			cout << "车票窗口三: " << tickets-- << endl;
		}
		else
		{
			break;
		}
		mtx.unlock();
		Sleep(1);
	}
	return 0;
}

///
int main(int argc, TCHAR* argv[])
{
	/*HANDLE hThread1;//Handler:是一个消息分发对象,进行发送和处理消息
	HANDLE hThread2;//Handler:无类型指针(不指向任何类型数据的指针)
	HANDLE hThread3;
					//创建线程
	hThread1 = CreateThread(NULL,//有没有安全性描述
		0,	//默认线程栈的大小(让新线程采用与调用线程一样的栈大小)
		Fun1, //指定线程的入口函数地址(线程函数指针)
		NULL,//这里就是你要传进Fun1函数的参数
		0,// 没有附加属性
		NULL);// 不需要获得线程id,线程创建标记,0表示让线程一旦创立就运行、新线程的ID,不需要的话为null


	hThread2 = CreateThread(NULL, 0, Fun2, NULL, 0, NULL);
	hThread3 = CreateThread(NULL, 0, Fun3, NULL, 0, NULL);

	CloseHandle(hThread1);  //调用CloseHandle将此线程的句柄关闭,关闭句柄时,系统会递减该线程内核对象的使用计数。
	CloseHandle(hThread2);
	CloseHandle(hThread3);

	Sleep(4000); //让线程暂停运行4s
	system("pause");
	return 0;
	*/

	std::thread t1(Fun1, "车票窗口一");
	std::thread t2(Fun2, "车票窗口二");
	std::thread t3(Fun3, "车票窗口三");

	t1.join();
	t2.join();
	t3.join();

	return 0;

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值