操作系统:模拟售票功能
以下程序是模拟售票功能,使用临界区对象,其中SellPro_1,SellPro_2两个函数分别对应两个售票进程,一次售出一张票。
//模拟售票程序
#include <windows.h>
#include <iostream>
using namespace std;DWORD WINAPI SellPro_1( LPVOID lpParameter);
DWORD WINAPI SellPro_2( LPVOID lpParameter );int tickets=100;
CRITICAL_SECTION critical_sec; //定义关键区域
void main()
{HANDLE hThread1;HANDLE hThread2;InitializeCriticalSection(&critical_sec); //初始化关键区域hThread1=CreateThread(NULL,0,SellPro_1,NULL,0,NULL);hThread2=CreateThread(NULL,0,SellPro_2,NULL,0,NULL); CloseHandle(hThread1);CloseHandle(hThread2);Sleep(4000);
}DWORD WINAPI SellPro_1( LPVOID lpParameter )
{ while(TRUE){ Sleep(1);EnterCriticalSection(&critical_sec); //进入关键代码区域 if(tickets>0){cout<<"thread1 sell ticket : "<<--tickets<<endl;}elsebreak;LeaveCriticalSection(&critical_sec); //离开代码关键区域} return 0;
}DWORD WINAPI SellPro_2( LPVOID lpParameter)
{ while(TRUE){ Sleep(1);EnterCriticalSection(&critical_sec); //进入关键代码区域 if(tickets>0){cout<<"thread2 sell ticket : "<<--tickets<<endl;}elsebreak;LeaveCriticalSection(&critical_sec); //离开代码关键区域} return 0;
}
DWORD WINAPI SellPro_1(LPVOID lpParameter);
DWORD:
1、代表 unsigned long,一般用于返回值不会有负数的情况。
2、typedef unsigned long DWORD;
关于DWORD使用中重要的一点。DWORD 现在表示 32bit 无符号整数,即使以后 Windows 升级到64位,DWORD 仍然是 32bit 无符号整数(也许以后的 long 不是32bit了,只需要重新定义一下 DWORD 就可以了)。对于那些直接和位数有关的整数,最好不用 int, long, short 之类的类型,因为这些类型的位数可能不确定(比如,在16位程序里,int 是16位的,在32位程序里,int 是32位的,谁知道在以后的64位程序里,int 是多少位,long 又是多少位)。用重新定义的类型就没有这方面的问题了,最多到时候修改一下定义就可以了,而不需要在程序里一行一行的查找
3、在实际情况中,DWORD会根据操作系统的不同,被定义成了不同的长度
4、C++中使用DWORD不用声明,但是要加头文件Windows.h。
(1)DWORD全称Double Word,是指注册表的键值,每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位,共32位。
(2)DWORD在Windows下经常用来保存地址(或者存放指针)。
DWORD WINAPI
DWORD是数据类型,WINAPI是函数调用形式,最终就是_stdcall形式,即由被调用函数来清理栈中的参数,这种方式是不能实现可变参数的。
WINAPI是个宏,一般会被代换为一个调用约定,通常为_stdcall,告诉编译器如何调用该函数。
_stdcall
被这个关键字修饰的函数,其参数都是从右向左通过堆栈传递的(__fastcall 的前面部分由ecx,edx传),
函数调用在返回前要由被调用者清理堆栈。
LPVOID
LPVOID是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针,比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法,然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来。
CRITICAL_SECTION
critical section是每个线程中访问临界资源的那段代码,不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问。
HANDLE
Windows操作系统中的一个概念
HANDLE:句柄,是Windows用来表示对象的(不是C++的对象),HWND是其中一种,HWND是HANDLE,但HANDLE不只是HWND,HANDLE是一个通用句柄表示,HWND是一个专用表示窗口的句柄。更具体的可查找MSDN。包含在winnt.h头文件中。
HANDLE(句柄)是Windows操作系统中的一个概念。在Windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为它们分配内存,并返回标示这些资源的标示号,即句柄。句柄指的是一个核心对象在某一个进程中的唯一索引,而不是指针。由于地址空间的限制,句柄所标识的内容对进程是不可见的,只能由操作系统通过进程句柄列表来进行维护。句柄列表:每个进程都要创建一个句柄列表,这些句柄指向各种系统资源,比如信号量,线程,和文件等,进程中的所有线程都可以访问这些资源。
InitializeCriticalSection
(API的功能)
功能——初始化临界区对象
格式:
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
参数说明:
lpCriticalSection——指向临界区对象的指针。
CreateThread
(API的功能)
功能——创建一个在调用进程的地址空间中执行的线程
格式:
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParamiter,
DWORD dwCreationFlags,
Lpdword lpThread );
参数说明:
lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。
dwStackSize——定义原始堆栈大小。
lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型定义的函数。
lpParamiter——定义一个给进程传递参数的指针。
dwCreationFlags——定义控制线程创建的附加标志。
lpThread——保存线程标志符(32位)
CloseHandle
CloseHandle包括文件、文件映射、进程、线程、安全和同步对象等。涉及文件处理时,这个函数通常与vb的close命令相似。应尽可能的使用close,因为它支持vb的差错控制。
参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。
关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。
若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
hObject Long,欲关闭的一个对象的句柄
注解
除非对内核对象的所有引用都已关闭,否则该对象不会实际删除
Sleep
SLEEP是一种函数,作用是延时,程序暂停若干时间,在执行时要抛出一个中断异常,必须对其进行捕获并处理才可以使用这个函数。
时间,就是他的参数,单位是毫秒。
EnterCriticalSection
(API的功能)
功能——等待指定临界区对象的所有权
格式
VOID enterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
参数说明
lpCriticalSection——指向临界区对象的指针。
LeaveCriticalSection
(API的功能)
功能——释放指定临界区对象的所有权
格式
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
参数说明
lpCriticalSection——指向临界区对象的指针。
操作系统:模拟售票功能相关推荐
- CRITICAL_SECTION的使用方法——模拟售票功能
模拟售票功能 1.以下程序是模拟售票功能,使用临界区对象,其中SellPro_1,SellPro_2两个函数分别对应两个售票进程,一次售出一张票. (1)阅读程序,了解CRITICAL_SECTION ...
- Enterprise Architect Professional操作系统特性和功能
Enterprise Architect Professional操作系统特性和功能 Enterprise Architect 64 位- Sparx Enterprise Architect 现在有 ...
- 练习-Java类和对象之对象引用之模拟手机功能
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 题目: 任务: 实现手机的基本功能. 手机具有属性:品牌(brand).型号(type).价格(price).操作系统(os)和内存( ...
- 1 操作系统第一章 操作系统概念、功能、四大特征、操作系统发展与分类
文章目录 1.1 操作系统概念 1.2 操作系统功能 1.3 操作系统四大特征 1.3.1 并发 1.3.2 共享 1.3.3 并发性和共享区别及对应关系: 1.3.4 虚拟 1.3.5 异步 1.4 ...
- 深入解析物联网操作系统(架构/功能/实例分析)
深入解析物联网操作系统(架构/功能/实例分析) 物联网的主要特点 i. 连接 所谓连接,指的是各种各样的终端设备,都能够通过某种网络技术,连接到一个统一的网络上.任何终端之间都可以相互访问.下一 ...
- IOT(29)---深入解析物联网操作系统(架构/功能/实例分析)
深入解析物联网操作系统(架构/功能/实例分析) 1. 物联网的主要特点 i. 连接 所谓连接,指的是各种各样的终端设备,都能够通过某种网络技术,连接到一个统一 ...
- 服务器系统的功能,服务器操作系统有什么功能
服务器操作系统有什么功能 内容精选 换一换 本章节指导用户通过控制面板卸载不需要的程序.本文以操作系统为"Windows Server 2016 Standard 64bit"的云 ...
- STM8学习笔记----普通IO口模拟串口功能
串口在产品应用中很常见,但是单片机的默认带的串口往往比较少,有时候就会出现串口不够用,所以就想着能不能用普通IO口模拟串口来实现串口的功能. 要模拟串口首先要清楚串口数据传输过程中的原理. 常用的串口 ...
- python实现模拟浏览器登录_Python使用win32com实现的模拟浏览器功能示例
本文实例讲述了Python使用win32com实现的模拟浏览器功能.分享给大家供大家参考,具体如下: # -*- coding:UTF-8 -*- #!/user/bin/env python ''' ...
最新文章
- R语言使用fs包的path_wd函数基于自定义文件路径规则,批量生成多个文件或者文件夹对应的绝对(absolute)文件路径(constructs absolute path)
- 六十.完全分布式 、 节点管理 、 NFS网关
- vivado2017.4安装教程
- linux系统root默认密码是多少钱,linux root默认密码忘记后的解决方法
- java限制在同一台电脑上只允许有一个用户登录系统
- 9.霍夫变换:圆——圆的算法、投票使用技巧、优点和缺点_2
- java9 javascript_JS(JavaScript)的j进一步了解9(更新中···)
- Android Eclipseproject开发中的常见调试问题(二)android.os.NetworkOnMainThreadException 异常的解决的方法...
- 【数据结构和算法笔记】线性表的查找(平均查找长度,二分法,判定树)
- 去除点击链接时出现的虚线框
- 公式推导 11-21
- python 微博自动点赞软件_python3 爬虫学习: 自动给你心上人的微博点赞
- python入门到精通,一篇就够。40个python游戏经典开源项目(开源分享:俄罗斯方块、魂斗罗、植物大战僵尸、飞机大战、超级玛丽...)
- mac使用svn命令基础篇
- Ubuntu 回收站目录
- MindMap学习使用
- 微信小程序申请医疗-就医服务类目解决办法
- Gitlab-runner 构建失败问题排查
- C语言用双曲线函数拟合曲线,c语言绘制函数曲线
- 紫光SSD评测:国产颗粒可与洋品牌一战