单例模式的多线程极端问题
2010-03-24 15:43
204 查看
刚刚同事贴了一个代码:
大牛的答案是,可能会有问题
原因在于编译器的实现与优化。如果,pInst = new T;转换成机器码时,是先将分配的地址空间赋值给pInst,(这时可能其他线程获取了pInst)然后再进行对象的初始化,可能其他线程调用的时候得到的是一个尚未进行初始化的对象...要解决这个问题就要用cpu的栅栏指令,阻止编译器调整机器码序列
代码如下:
#define barrier() __asm__ volatile ("lwsync")//powerpc提供的栅栏指令 volatile T* pInst = 0;
T* GetInstance()
{
if (pInst == NULL)
{
lock();
if (pInst == NULL)
T* temp = new T;
barrier();
pInst = temp;
unlock();
}
return pInst;
} 这样的问题估计VC或者GCC都不会有问题,但不保证其他编译会不会出问题。问题来自:程序员的自我修养 那本书第一章
volatile T* pInst = 0; T* GetInstance() { if (pInst == NULL) { lock(); if (pInst == NULL) pInst = new T; unlock(); } return pInst; }上面那段代码是单例模式的一个实现,多线程并发时候会不会有问题?
大牛的答案是,可能会有问题
原因在于编译器的实现与优化。如果,pInst = new T;转换成机器码时,是先将分配的地址空间赋值给pInst,(这时可能其他线程获取了pInst)然后再进行对象的初始化,可能其他线程调用的时候得到的是一个尚未进行初始化的对象...要解决这个问题就要用cpu的栅栏指令,阻止编译器调整机器码序列
代码如下:
#define barrier() __asm__ volatile ("lwsync")//powerpc提供的栅栏指令 volatile T* pInst = 0;
T* GetInstance()
{
if (pInst == NULL)
{
lock();
if (pInst == NULL)
T* temp = new T;
barrier();
pInst = temp;
unlock();
}
return pInst;
} 这样的问题估计VC或者GCC都不会有问题,但不保证其他编译会不会出问题。问题来自:程序员的自我修养 那本书第一章
相关文章推荐
- Singleton 模式的问题探究及多线程下设计问题
- 单例模式解决多线程的问题
- C#垃圾回收问题--》多线程的不安全性--》单例模式
- UWA 新功能| 多线程模式下也能定位堆内存问题了!
- JAVA学习第二十五课(多线程(四))- 单例设计模式涉及的多线程问题
- java多线程之单例模式和其DCL问题
- 多线程三,同步函数、静态同步函数和单例设计模式中懒汉式即延迟加载模式的多线程问题(毕向东老师)
- 设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题
- 单例模式的懒汉式在多线程的问题
- 哲学家进餐问题-状态模式 + 多线程
- JAVA多线程 <三>单例模式下的多线程问题
- Java多线程 -- 单例模式的Double-checked Locking (DCL)问题
- JAVA学习第二十五课(多线程(四))- 单例设计模式涉及的多线程问题
- 关于单例模式和多线程之间无法实现的问题
- Spring单例模式多线程安全问题-有状态的Bean
- 解决多线程下单例模式中"懒汉模式"(延迟加载)的问题
- double check 解决单例模式的多线程并发问题
- 关于多线程在简单的懒汉模式下线程安全问题的解决
- 19-多线程(验证同步函数的锁) 21-多线程(单例模式涉及的多线程问题) 1 2 22-多线程(死锁示例) 23-Objcet放的位置产生的问题