Singleton、MultiThread、Lib——实现单实例无锁多线程安全API
一、singleton double check
SingleInstance* volatile g_instance = NULL; cswuyg::MyCritical g_cs; SingleInstance* GetInstance() {if (g_instance == NULL){cswuyg::Lock<> lock(g_cs);if (g_instance == NULL){g_instance = new SingleInstance;}}return g_instance; }
MemoryBarrier宏
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686355(v=vs.85).aspx
这篇文章表示,vs2005以后的volatile已经包含了memory barrier的功能,并介绍了有几类函数是不会被调换执行顺序的。
http://stackoverflow.com/questions/19652824/why-can-memorybarrier-be-implemented-as-a-call-to-xchg/19652910#19652910
它介绍了为什么x86机器上的xchg可以消灭掉CPU的reorder。
二、导出Lib中慎用全局对象 & 原子操作代替锁
SingleInstance* volatile g_instance; LONG volatile g_for_lock; SingleInstance* GetInstance() {if (g_instance == NULL){LONG pre_value = ::InterlockedExchange(&g_for_lock, 1);if (pre_value != 0){while(g_instance == NULL){::Sleep(55);}}if (g_instance == NULL){g_instance = new SingleInstance;}}return g_instance; }
全局的g_for_lock在PE文件装入内存时就初始化为0,所以不存在初始化问题;InterlockedExchange 适用于xp、win7、win8,不存在系统限制;多个线程同时调用InterlockedExchange,只能有一个线程得到0,保证只初始化一次,其余线程进入while循环等待,直到g_point非空。问题不逼你,你就不会想到还有这么好的实现思路 :)
使用原子操作还可以很容易的实现临界区锁的功能,这里就不说了。
三、PE文件中的Lib库全局变量
Double Check 相关资料(主要是说执行指令调整导致在多核机器上某个线程会返回半成品对象,导致DoubleCheck思路失效):
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://zh.wikipedia.org/wiki/%E5%8F%8C%E9%87%8D%E6%A3%80%E6%9F%A5%E9%94%81%E5%AE%9A%E6%A8%A1%E5%BC%8F
2014.3.8补充:
抛出异常问题:对于导出API还需要注意不能影响到使用者进程的运行,所以不能抛出exception,需要这么做:1、在API实现处,使用__try...__except把所有逻辑封起来;2、在API的入口处设置非法参数、纯虚函数调用错误处理(_invalid_parameter_handler、_set_purecall_handler),并在出口处还原以便不修改外界设置,这里要解决的是CRT抛出的错误,它跟SEH没关系,所以使用__try...__except无法catch住,这两函数的相关知识参考:《windows下的dump捕获》http://www.cnblogs.com/cswuyg/p/3207576.html。
2014.3.13补充:
编译依赖问题:EXE C依赖Lib B,Lib B依赖Lib A,如果Lib A使用了预编译,那么会出现这种链接错误:error LNK2011: precompiled object not linked in; image may not run,有两种解决方案:1、让EXE C能接触到Lib A工程,保证EXE C在链接的时候能找到Lib A所有相关的中间产物,这个方案我不能采用,因为对外提供的只是Lib B SDK,不是源码;2、Lib A不使用预编译,这个方案比较方便,不过不使用预编译后会增加编译时间,由于Lib A工程比较小,可以接受。 另外,Lib B如何包含Lib A的问题可以参考:http://www.cnblogs.com/cswuyg/archive/2012/02/03/2336424.html
转载于:https://www.cnblogs.com/cswuyg/p/3575022.html
Singleton、MultiThread、Lib——实现单实例无锁多线程安全API相关推荐
- 单实例设计模式的实现
2019独角兽企业重金招聘Python工程师标准>>> 今天中午看到一个面试题,是这样的,"怎样设计一个类,使其只能有一个实例",知道设计模式的程序员可能很快就能 ...
- Singleton设计模式(单实例)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 深入浅出单实例Singleton设计模式
深入浅出单实例Singleton设计模式 陈皓 前序 单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了.这个设计模式主要目的是想在整 ...
- Java并发基础:了解无锁CAS就从源码分析
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
- python编写单实例总结
python编写单实例总结 1 单实例的属性都可以在__init__方法中按照sell.x=x添加 2 实例内部某方法调用实例另一方法用self方式 def fun1(self,x): re ...
- 理解 Memory barrier(内存屏障)无锁环形队列
Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的性能.内存乱序访问主要发生在两 ...
- Java并发编程,无锁CAS与Unsafe类及其并发包Atomic
为什么80%的码农都做不了架构师?>>> 我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...
- Java并发基础:了解无锁CAS就从源码分析 1
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
- linux下程序如何实现单实例运行
1.技术原理 无论是windows还是linux下,程序设计者都会遇到一个问题,那就是如何实现程序的单实例运行.比如,Windows自带的播放软件Windows Medea Player只能启动一个实 ...
最新文章
- JakartaEE Exception: Invalid bound statement (not found): com.mazaiting.blog.dao.UserDao.selectUs...
- 生物信息学 几个程序
- 使用OpenSSL实现证书操作
- Laravel的console使用方法
- java amp amp 怎么用,java中amp;与amp;amp;的区别
- python PIL 生成照片墙
- getpass函数简单使用
- android:SQlite
- 解决:liunx 光标消失(显示光标)
- PowerShell 2.0 实践(十一)管理 TFS 2010 (2)
- 雨果vs.杰基尔:比较领先的静态网站生成器
- 函数式编程(4)-装饰器
- python和uipath区别_Uipath中调用Python的方法
- linux 软raid配置-系统安装
- 为 Retrofit2 提供的 FastJson 转换库
- codeforces [Gym-100814E]
- jquery点击图片放大功能
- 接口测试平台-18:首页完善和项目模块初窥
- python实现猜测随机数
- FST(Finite-State Transducer) 原理
热门文章
- 浅析关键词与搜索引擎之间不得不说的关系
- 以营销型网站为例,网站建设过程中需要注意哪些问题?
- linux 强制刷新文件,vim 如何刷新或重载reload 已打开的文件
- 获取打印机分辨率_喵喵机P2S热敏打印机,升级屏幕带来了哪些体验??
- vue 企业发展历程动画_「咻动画」企业宣传片可以在哪些方面应用?
- 建模大师怎么安装到revit中_「Revit技巧」插件挤满了、冲突了,怎么办?
- 将TensorFlow模型变为pb——官方本身提供API,直接调用即可
- es的forcemerge——按照天分割
- 深入理解angularjs $watch ,$apply 和 $digest --- 理解数据绑定过程
- Mybatis 配置文件