win32的计数增减操作的原子操作--InterLockedIncrement和InterlockedDecrement
InterLockedIncrement and InterLockedDecrement
实现数的原子性加减。
什么是原子性的加减呢?
举个例子:如果一个变量 Long value =0;
首先说一下正常情况下的加减操作:value+=1;
1:系统从Value的空间取出值,并动态生成一个空间来存储取出来的值;
2:将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束。
如果此时有两个Thread ,分别记作threadA,threadB。
1:threadA将Value从存储空间取出,为0;
2:threadB将Value从存储空间取出,为0;
3:threadA将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
4:threadB将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
最后Value =1 ,而正确应该是2;这就是问题的所在,InterLockedIncrement 能够保证在一个线程访问变量时其它线程不能访问。同理InterLockedDecrement。
LONG InterlockedDecrement(
LPLONG lpAddend // variable address
);
属于互锁函数,用在同一进程内,需要对共享的一个变量,做减法的时候,
防止其他线程访问这个变量,是实现线程同步的一种办法(互锁函数)
首先要理解多线程同步,共享资源(同时访问全局变量的问题),否则就难以理解。
result = InterlockedDecrement(&SomeInt)
如果不考虑多线程其实就是 result = SomeInt - 1;
但是考虑到多线程问题就复杂了一些。就是说如果想要得到我预期的结果并不容易。
result = SomeInt - 1;
举例说:
SomeInt如果==1;
预期的结果result当然==0;
但是,如果SomeInt是一个全程共享的全局变量情况就不一样了。
C语言的"result = SomeInt - 1;"
在实际的执行过程中,有好几条指令,在指令执行过程中,其它线程可能改变SomeInt值,使真正的结果与你预期的不一致。
所以InterlockedDecrement(&SomeInt)的执行过程是这样的
{
__禁止其他线程访问 (&SomeInt) 这个地址
SomeInt --;
move EAX, someInt; // 设定返回值,C++函数的返回值 都放在EAX中,
__开放其他线程访问 (&SomeInt) 这个地址
}
但是实际上只需要几条指令加前缀就可以完成,以上说明是放大的。
你也许会说,这有必要吗? 一般来说,发生错误的概率不大,但是防范总是必要的
如果不考虑多线程
result = InterlockedDecrement(&SomeInt);
就是result = SomeInt - 1;
如果SomeInt==1,result一定==0;
但是,在多线程中如果SomeInt是线程间共享的全局变量,情况就不那么简单了。
result = SomeInt - 1;
在CPU中,要执行好几条指令。在指令中间有可能SomeInt被线程修改。那实际的结果就不是你预期的结果了。
InterlockedDecrement(&SomeInt)
放大的过程,如下:
{
__禁止其他线程访问 &SomeInt 地址;
SomeInt --;
/////其他线程不会在这里修改SomeInt值。 !!!!!!
mov EAX, SomeInt; //C++ 函数返回值 总放在EAX中。
__开放其他线程访问 &SomeInt 地址;
}
实际的CPU执行过程只有几条加前缀的指令(586指令)
你会说,有必要吗? 出错的概率不大,但是错误总是需要防范的。当然可以用其他多线程机制实现,但是都没有这样简洁,所以Interlocked...函数有必要提供。
win32的计数增减操作的原子操作--InterLockedIncrement和InterlockedDecrement的更多相关文章
- 前端和后台对时间数值的增减操作(JavaScript和C#两种方法)
最近在做一个视频回放项目,记录下一点总结. 应用背景: 假设有一个门禁系统记录着门禁的人员进出刷卡信息,门禁装有视频录像设备,现在要根据人员的刷卡时间调出其刷卡时间点前后一段时间的录像.关于视频回放部 ...
- Linux 内核引用计数的操作
一个 kobject 的其中一个关键函数是作为一个引用计数器, 给一个它被嵌入的对象. 只 要对这个对象的引用存在, 这个对象( 和支持它的代码) 必须继续存在. 来操作一个 kobject 的引用计 ...
- 【C#】分享基于Win32 API的服务操作类(解决ManagedInstallerClass.InstallHelper不能带参数安装的问题)
注:这里的服务是指Windows 服务. ------------------201508250915更新------------------ 刚刚得知TransactedInstaller类是支持带 ...
- win32下利用python操作printer
在win32下操作printer: 1)import win32print 2) 获得默认打印机名: >>> win32print.GetDefaultPr ...
- Win32中目录的操作
1 系统和当前目录 1.1 获取Windows目录 UINT GetWindowsDirectory( LPTSTR lpBuffer, //BUFF的地址 UINT uSize //BUFF ...
- Win32中文件的操作
1 文件的创建或打开 HANDLE CreateFile( LPCTSTR lpFileName, //文件路径和名称 DWORD dwDesiredAccess, //访问方式,最常用的值 ...
- Win32 基本文件读写操作
https://www.cnblogs.com/Clingingboy/archive/2011/05/10/2042645.html
- InterLockedIncrement and InterLockedDecrement函数原理
实现数的原子性加减. 什么是原子性的加减呢? 举个样例:假设一个变量 Long value =0; 首先说一下正常情况下的加减操作:value+=1. 1:系统从Value的空间取出值,并动态生成一个 ...
- 多线程笔记--原子操作Interlocked系列函数
前面写了一个多线程报数的功能,为了描述方便和代码简洁起见,只输出最后的报数结果来观察程序运行结果.这非常类似一个网站的客户访问统计,每个用户登录用一个线程模拟,线程运行时将一个表示计数的变量递增.程序 ...
随机推荐
- 程序4-2 access函数实例
//http://blog.chinaunix.net/uid-24549279-id-71355.html /* ========================================== ...
- android中状态栏透明
设置 Acitivity 所在 window 的属性 @Override protected void onCreate(Bundle savedInstanceState) { super.onCr ...
- linux 目标文件 bss,data,text,rodata,堆,栈***
linux目标文件 一个简单的程序被编译成目标文件后的结构如下: 从图可以看出,已初始化的全局变量和局部静态变量保存在 .data段中,未初始化的全局变量和未初始化的局部静态变量保存在 .bss段中. ...
- Vue.js:起步
ylbtech-Vue.js:起步 1.返回顶部 1. Vue.js 起步 每个 Vue 应用都需要通过实例化 Vue 来实现. 语法格式如下: var vm = new Vue({ // 选项 }) ...
- 1039 Course List for Student
题意:给出K门课程(编号1~K)以及报名该课程的学生,然后有N个学生查询,对于每一个查询,输出该学生所报的相关课程编号,且要求编号按增序输出. 思路:题目不难,解析略.(本来用map直接映射,用STL ...
- Build Assetbundle出错:An asset is marked as dont save, but is included in the build
前天Build Assetbundle的时候出错了,导致打包失败,具体日志内容如下: An asset is marked as dont save, but is included in the b ...
- oracle ---中文乱码问题
---- 1.原因分析 ---- 通过对用户反映情况的分析,发现字符集的设置不当是影响ORACLE数据库汉字显示的关键问题.那么字符集是怎么一会事呢?字符集是ORACLE 为适应不同语言文字显示而设定 ...
- Java面向对象-String类
1,实例化String对象 有两种方式,我们直接看代码: package com.java1234.chap03.sec08; public class Demo1 { public static v ...
- Axure RP的基础使用
Axure RP是一个专业的快速原型设计工具. 在上面可以直接设计软件的原型而且不涉及代码,例如设计软件的流程和界面之类的.简单的说,就是可以在上面编写界面,让人看起来像一个完整的软件一样. 设置完成 ...
- python学习——练习题(1)
""" 题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? """ import itertools d ...