Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increased multithreading security #463

Merged
merged 2 commits into from
Nov 20, 2023
Merged

Increased multithreading security #463

merged 2 commits into from
Nov 20, 2023

Conversation

xfmy
Copy link
Contributor

@xfmy xfmy commented Nov 19, 2023

1.instance()

修改点

修改前:instance()函数中使用的是双重校验锁,

修改后:instance()中使用std::call_once替换双重校验所,增加多线程下线程安全性

问题

问题主要出在内存模型和可见性上。在多线程环境中,可能存在指令重排或内存可见性的问题。因此,在第一次检查和初始化之间,另一个线程可能会看到某个对象已经被分配内存但尚未被完全初始化的情况,这可能导致使用未完全初始化的对象,从而产生不确定的行为。

:首先new一个对象时,分为三个步骤,1分配内存 2构造对象 3返回指针。所以常规顺序是123,但是编译器有时候为了优化会指令重排,导致顺序变成132,这里我们考虑这么一种情况
A线程:new1分配内存并按照指令重拍之后的顺序将2地址返回s_pInstance指针(这时候s_pInstance指针是非空的,但是还没有到达构造构造,此时时间片用完,线程切换)
B线程进入,此时发现s_pInstance是非空的,便直接将s_pInstance返回给调用者,而调用着使用这个没有构造的对象将会发生不可预测的后果

指令重拍原因很多,比如编译器优化或者cpu指令流水线导致

2.exitInstance()

修改前:exitInstance() 函数原本使用mutex的lock()和unlock()

修改后:使用lock_guard替换mutex,避免delete之前存在异常,导致mutex锁无法正确释放

@@ -14,28 +14,23 @@
private: \
DISABLE_COPY(Class) \
static Class* s_pInstance; \
static std::once_flag initFlag; \
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

统一下命名规范吧,static变量使用s_开头

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好了,已经统一命名规范了

@ithewei ithewei merged commit a5b3744 into ithewei:master Nov 20, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants