线程与进程(c++ windows)

关于线程与进程的解释:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html


#include <windows.h>
#include <iostream>
using namespace std;
// 对于不好重现的错误 修改起来是很麻烦的 
//线程数据同步 一个线程在访问一个资源的时候 其他的线程不能对这个资源的访问
//windows 用互斥对象 来同步线程间的数据 实现同时只能有一个线程来访问这个数据
//互斥对象  内部一个 线程ID 记录当前那个线程拥有该互斥对象  还有一个计数器

//线程函数
DWORD WINAPI fun1Proc(
	LPVOID lpParanrter
	);

DWORD WINAPI fun2Proc(LPVOID lpPar);
int index = 0;
int tickets = 100;
HANDLE hMutex;
int main()
{
	HANDLE hThread1;
	hThread1 = CreateThread(NULL,0, fun1Proc, NULL, 0, NULL);
	HANDLE hThread2;
	hThread2 = CreateThread(nullptr, 0, fun2Proc, NULL, 0 , nullptr);
	CloseHandle(hThread1);
	CloseHandle(hThread2);
	//while(index++ < 1000)
	//	cout << "main thread is running" << endl;
	//暂停线程 参数的毫秒数的运行时间 同时放弃运行 
	//CPU会切换到其他线程运行 其他线程运行完 该线程会接着sleep下一步运行
	//Sleep(2); 

	//创建一个匿名的互斥对象
	//第二个参数为 false 当前没有线程 拥有互斥对象 操作系统会把它置为有信号状态
	hMutex = CreateMutex(nullptr, false, nullptr);
	//主线程退出 子线程会跟着退出  所以要保证 子线程运行时间内 主线程不能退出 
	//不能用死循环来代替 会占用CPU 时间片
	Sleep(4000);
	cin.get();
	return 0;
}

DWORD WINAPI fun1Proc(
	LPVOID lpParanrter
)
{
	//线程函数执行完  线程就退出了 要想线程一直存在 要+一个循环
	while(true)
	{
		//获取互斥对象状态 参数2 timeout(永远等待) 互斥对象状态为无信号 永远等待 
		//等待期间 其他线程会运行 直到互斥对象为有信号 才能继续运行
		//如果互斥对象有信号 该函数会把 互斥对象的线程ID 置为该线程的ID
		//同时把 互斥对象 置为 无信号
		WaitForSingleObject(hMutex, INFINITE);
		if(tickets > 0)
		{	
			Sleep(1); // 会导致出错 卖出0这张票 加入互斥对象 不会出错
			cout << "thread1  sell ticket : " << tickets-- << endl;
		}
		else
			break;
		//释放互斥对象 让互斥对象有信号 把互斥对象内部线程ID设置为0, 
		//其他的线程就可以得到互斥对象的所有权 
		//释放互斥对象  线程ID 会与 hMutex的线程ID 比较 相等才能释放互斥对象
		//别的线程 是不能释放 当前线程的互斥对象的
		ReleaseMutex(hMutex);
	}
	/*while(index++ < 1000)
		cout << "thread1 is running" << endl;*/
	return 0;
}

DWORD WINAPI fun2Proc(LPVOID lpPar)
{
	//如果互斥对象请求和释放 放在while 循环外面 线程2会一直拥有该互斥对象 释放不了 因为下面是一直执行的循环
	//WaitForSingleObject(hMutex, INFINITE);
	while(true)
	{
		//互斥对象 内部有线程ID 与 引用计数  如果拥有互斥对象的线程 再请求互斥对象 还能请求
		//引用计数会+1  ReleaseMutex 会让引用计数-1 引用计数为0 才会让 互斥对象有信号
		//如果一个对象得到互斥对象之后 线程终止 没有释放互斥对象 操作系统会自动释放该互斥对象 最好自己释放
		//WaitForSingleObject 返回值会 看出是 该互斥对象 终止的状态
		WaitForSingleObject(hMutex, INFINITE);
		if(tickets > 0)
		{	
			Sleep(1); //会导致出错 卖出0这张票
			cout << "thread2  sell ticket : " << tickets-- << endl;
		}
		else
			break;
		// 互斥对象 相当于只有一把钥匙 一个在使用 别人就不可以使用 
		ReleaseMutex(hMutex);
	}
	//ReleaseMutex(hMutex);
	return 0;
}

//一些软件 如何自己已经有一个 程序实例了 
//CreateMutex 创建一个有名字的互斥对象 如果已经有该互斥对象 就会返回以前的互斥对象的句柄
//getLastError 可以查看有名字的 互斥对象的句柄 是不是已经存在
//应用命名的互斥对象  会让程序 同时只能有一个实例在运行

//hMutex = CreateMutex(nullptr, true, "tickets");
//if(hMutex)
//{
//	if(ERROR_ALREADY_EXISTS == GetLastError())
//	{
//		cout << "only instance can run!" << endl;
//		return ;
//	}
//}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值