多线程环境下,程序真是危机四伏

简介: 本文依旧是#线程安全#、#锁# 这两个老生常谈的概念的延续, 我的知识体系也是在不断迭代更新,不断精炼。

你管这也叫线程安全?


      最近大意了,竟然想将《面试官:实现一个带值变更通知能力的Dictionary》一文中的临界锁只应用到写操作。


d950f7b8b45f46862eb430cd300af282.png


内心旁白:读操作又不会修改数据,无论是新值还是旧值,反正能读到。


不过我又快速清醒了,临界锁还真就得这么加。临界锁的目的是保证这一段代码逻辑不会被打断。


假如只应用写锁:

07152574f9a82dd2c5ec6196936c25de.png


某线程执行到写锁前(刚触发了一次变通通知),这时cpu时间片轮转或抢占, 切换到另外的线程又把这段代码执行了一次(因为字典key-value还没被前线程覆写),这样一次value变更实际执行了两次变更操作,这就悲剧了。


结合之前《你管这叫线程安全?》一文中多线程对于i++i--带来的线程不安全的理解。


你品你细品:


本次线程安全是在宏观代码行执行层面, 上次的i++ 是在微观寄存器层面归根到底让多线程在多核环境下:代码逻辑不能被打断(代码执行节奏可能被打断)


多线程环境下,程序运行真是危机四伏。


微软官方怎么说?


还没完, 我还从微软官方原子操作[1]找到一段话:


Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list are also atomic. Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, are not guaranteed to be atomic. Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.


直译起来:


① bool char byte sbyte uint int float 和引用类型上的读写是原子操作;

② 由以上类型定义的枚举类型操作也是原子类型;

③ long ulong double decimal和用户定义类型上的读写不保证是原子操作;

④ 除了库文件本身设计了线程安全,一般况下下都不保证读写是原子操作, 这也包括i++i--


这段文字是不是刷新了某些童靴的认知(包括在下):


1. 以后使用long num=8888;时要留个心眼,你也许会读到long类型的部分字节。


2.直译第①点说引用类型的读写是原子操作,第③点说用户类型不保证原子操作,但是大部分的用户类型是引用类型,这不互相矛盾了吗?


我向微软官方提出了我的这个疑问,有兴趣可以关注这个 github issue[2]


说说我的看法:


直译第①点中说int,引用类型等读写操作是原子操作:应该想表达的是纯粹的赋值操作, 比如


int a =1;                               //  赋值:线程安全Student s = new Student {};             // 引用赋值:线程安全Student  s2= s;                         // 引用赋值:线程安全


针对引用类型Dictionary的其他操作自然不是线程安全的。


依据这个思路, 第①③点就不矛盾了。


That's All, 本文依旧是#线程安全#、#锁# 这两个老生常谈的概念的延续, 我的知识体系也是在不断迭代更新,不断精炼。

相关文章
|
29天前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
58 0
|
1月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
1月前
|
缓存 安全 Java
为什么全局变量可能成为多线程环境中的安全隐患
为什么全局变量可能成为多线程环境中的安全隐患
|
2月前
|
人工智能 Java API
Python 潮流周刊#28:两种线程池、四种优化程序的方法
Python 潮流周刊#28:两种线程池、四种优化程序的方法
23 1
|
1月前
|
消息中间件 Java 数据库连接
【C++ 多线程】C++ 多线程环境下的资源管理:深入理解与应用
【C++ 多线程】C++ 多线程环境下的资源管理:深入理解与应用
37 1
|
1月前
|
缓存 编译器 程序员
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
62 0
|
2月前
|
存储 安全 Python
如何在Python中实现一个单例模式,确保在多线程环境中也是安全的?
【2月更文挑战第5天】【2月更文挑战第11篇】如何在Python中实现一个单例模式,确保在多线程环境中也是安全的?
|
2月前
|
安全 Java 开发者
Python多线程编程实战:提高程序执行效率的策略
Python多线程编程实战:提高程序执行效率的策略
124 1
|
2月前
|
Java
如何在Java中使用多线程提高程序性能
【2月更文挑战第2天】在当今的计算机应用领域中,性能是一个不可忽视的重要因素。为了提高程序的性能,我们可以采用多种方法。其中一种方法是使用多线程。本文将介绍如何在Java中使用多线程来提高程序性能。
23 2
|
3月前
|
安全
多线程和异步编程:什么是线程安全?如何确保在多线程环境下的数据安全性?
多线程和异步编程:什么是线程安全?如何确保在多线程环境下的数据安全性?
56 3