windows多线程--原子操作
推荐参考博客:秒杀多线程第三篇 原子操作 Interlocked系列函数
原子操作 VS 非原子操作
原子操作就是不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程切换。 本文地址
首先从一个简单的例子来看,1000个线程同时对一个全局变量(初始化为0)做++操作,最后我们期望的这个变量的值是1000,但是有时候结果却事与愿违:
#include<string>#include<iostream>#include<process.h>#include<windows.h>using namespace std;volatile int g_cnt;unsigned __stdcall threadFun(void *param)
{g_cnt++;return 0;
}int main()
{for(int j = 0; j < 100; j++){g_cnt = 0;const int threadNum = 1000;HANDLE hth[threadNum];for(int i = 0; i < threadNum; i++)hth[i] = (HANDLE)_beginthreadex(NULL, 0, threadFun, NULL, 0, NULL);//注意WaitForMultipleObjects每次最多等待MAXIMUM_WAIT_OBJECTS个object;//也可以调用1000次WaitForSingleObjectint k = threadNum / MAXIMUM_WAIT_OBJECTS;for(int i = 0; i < k; i++)WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS,&hth[i*MAXIMUM_WAIT_OBJECTS],TRUE, INFINITE);if(threadNum % MAXIMUM_WAIT_OBJECTS != 0)WaitForMultipleObjects(threadNum % MAXIMUM_WAIT_OBJECTS,&hth[k*MAXIMUM_WAIT_OBJECTS],TRUE, INFINITE);for(int i = 0; i < threadNum; i++)CloseHandle(hth[i]);if(g_cnt != 1000)cout<<"the value of g_cnt: "<<g_cnt<<endl;}
}
为什么会这样呢,因为g_cnt++不是一个原子操作,在vs2010中查看反汇编代码为:
对于++操作,编译器把它分为三步:1、从内存中吧g_cnt的值读到寄存器eax,2、eax中的值+1, 3、把eax中的值写会内存
如果有两个线程,线程1执行到第二条语句时,线程2开始执行,那么线程2获取的g_cnt的值还是原来的0(因为线程1还没有执行低三条语句来写回内存),最后g_cnt的值就是1,而不是期望的2;
windows系统提供给了一些函数来保证某些操作的原子性:
LONG __cdecl InterlockedIncrement(LONG volatile* Addend); //变量加1
LONG __cdecl InterlockedDecrement(LONG volatile* Addend);//变量减1
LONG __cdec InterlockedExchangeAdd(LONG volatile* Addend, LONG Value);//变量加上value
LONG __cdecl InterlockedExchange(LONG volatile* Target, LONG Value);//将value的值 赋值 给target指向的变量
以上列出的函数是针对32位的LONG数据的,如果是64位的数据,有其对应的函数,具体可以参考 msdn 列出的所有原子操作函数
针对上面的问题,我们可以把g_cnt++; 改为 InterlockedIncrement((LONG volatile *)&g_cnt);
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3602426.html
转载于:https://www.cnblogs.com/TenosDoIt/p/3602426.html
windows多线程--原子操作相关推荐
- windows多线程同步互斥--总结
2019独角兽企业重金招聘Python工程师标准>>> 秒杀多线程面试题系列 参考JustDoIT -- 大部分内容 <Windows核心编程>线程同步对象速查表 对象 ...
- Windows多线程编程总结
Windows 多线程编程总结 keyword:多线程 线程同步 线程池 内核对象 1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这样的内存块是一个数据结构,表示内核对象的各 ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率比较 ...
- Windows多线程控制台程序
学习笔记 Windows多线程控制台程序目的:学习和掌握如何编写Windows多线程控制台程序.通过编写程序,加深对进程和线程关系的理解,掌握多线程程序的执行和编写技巧.设计要求:写一个单进程多线程的 ...
- 【转】windows多线程CreateThread与_beginthreadex本质区别
本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...
- windows多线程详解
转自:http://blog.csdn.net/zhouxuguang236/article/details/7775232 在一个牛人的博客上看到了这篇文章,所以就转过来了,地址是http://bl ...
- java 多线程 原子操作_线程安全之原子操作
原子操作 原子性就是指该操作是不可再分的.不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作. 原子操作可以是一个步骤,也可以是多个步骤,但是其顺序不可以被打乱,也不可以被切割而 ...
- Windows多线程多任务设计初步zz
[前言:]当前流行的Windows操作系统,它能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程 ...
- IDM 下载工具利器 - 经典好用优秀的 Windows 多线程加速下载软件
简介 如果你是一名互联网"老司机",那么一定听过「IDM」这款下载工具的大名!它的全名叫做 Internet Download Manager (互联网下载管理器),缩写就是 ID ...
最新文章
- 35岁之后,你还会继续写代码吗?
- vue init webpack缺少标识符_vue 如何从单页应用改造成多页应用_vue.js
- ios 隔空投安装ipa_ipa文件是什么?怎么安装ipa文件到苹果手机上?
- 使用RichTextBox控件实现系统剪切板功能
- uvalive 4973 Ardenia
- Sublime Text 3 初试牛刀
- dev c++ 代码补全_zsh配置与代码自动补全+tmux配置
- 根据流程部署ID来获取流程定义图片
- [SAP ABAP开发技术总结]ABAP调优——代码优化
- 网吧用服务器做虚拟化,刀片、无盘、集群、虚拟化,给你一个选择的理由(上)...
- 分子动力学软件-OVITO
- PWM波的原理和应用
- Python编程之求累乘和
- 物联网安全架构与基础设施
- google浏览器被2345强制绑定
- 运筹学基础(名词解释题总结)
- c语言程序设计论文背单词系统,C语言课程设计-背单词系统(含程序)
- 『语音信号处理』语音库 librosa 学习
- 【日常学习】【二分】【单调队列优化线性DP】codevs3342 绿色通道题解
- 参考ggplot2,Seaborn将迎来超大版本更新!
热门文章
- java 整数变负数_年年有余之java求余的小技巧
- matlab去趋势,[转载]使用Matlab对数据进行去趋势(detrend)
- java内存溢出排查top_process-parse-shell
- mysql用户权限与安全实例_mysql用户权限管理实例分析
- njx如何实现负载均衡_使用Nginx实现负载均衡
- transformers Tokenizer
- 03 unix 设计哲学和流重定向
- MySQL Create Table
- 1.11 为什么使用卷积?
- opencv-api getAffineTransform()