Python 中 有 CAS 的实现吗

2021-10-18 11:33:15 +08:00
 monetto

Google 了一下 "Python" "CAS",只是搜到了一些关于 GIL 的 ATOMIC 操作。

但是觉得 Python 的 Lock() 又有点沉,有大佬知道有没有类似 CAS 的轻量级实现吗?

5350 次点击
所在节点    Python
51 条回复
sujin190
2021-10-19 13:58:08 +08:00
def f():
...: a=1
...: b=a


2 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)

3 4 LOAD_FAST 0 (a)
6 STORE_FAST 1 (b)
8 LOAD_CONST 0 (None)

@junkun #26 一个赋值语句两条字节码组成,以 Python 的内存结构来说,其实就算被拆开其实越不会有副作用,所以认为是原子操作其实也没有啥问题
sujin190
2021-10-19 14:02:42 +08:00
@monetto #39 Python 的 GIL 就是用来保证内部数据结构线程安全的,否则直接删掉 GIL 就是了啊,所以肯定必须要求是单条字节码完整执行完成才能切换,不可能像操作系统线程一样时间一到啥都不管就直接切换吧,否则 Python 内部自身的数据结构都有可能被破坏了,从这一点上来说,GIL 保证单条字节码的完整性,确实提供了大量线程安全的操作,比如赋值,不能说毫无关系吧
monetto
2021-10-19 14:29:50 +08:00
@sujin190 嗯嗯,毫无关系确实不至于,对象内部的线程安全确实没错,不过问题是只有 CPython 存在 GIL,JPython 是没有的。
dingyaguang117
2021-10-20 08:57:52 +08:00
@sujin190 GIL 是用来保证对象内部线程安全怎么理解,什么是内部对象,那些场景线程安全?
dingyaguang117
2021-10-20 09:11:40 +08:00
@sujin190 应该是只有单字节码的操作才能保证线程安全。a=a+1 应该都不是
dingyaguang117
2021-10-20 09:13:50 +08:00
@monetto GIL 锁不能完全解决线程安全问题,举个例子:一个线程遍历 dict,另一个删除。线程安全问题不仅是一行语句的安全
monetto
2021-10-20 10:24:14 +08:00
@dingyaguang117 晕...我上面不是说了吗...保证对象的 pop,append 线程安全,内部的,不是两个线程同时操作。我没说两个线程同时操作线程安全。因为 pop 和 append 是 C 语言调用,C 语言调用的都是 ATOMIC 的。
monetto
2021-10-20 10:25:15 +08:00
@dingyaguang117 人家说的是内部数据结构,是 pop,remove 等内部的操作,不是让你两个线程同时操作的...理解错了吧兄弟
sujin190
2021-10-20 12:18:15 +08:00
@dingyaguang117 Python 解释器也需要用内存,也有数据结构啊,编译,创建类,模块导入,线程创建,文件操作,套接字这些底层也是用 GIL 保证线程安全的吧
sujin190
2021-10-20 12:27:06 +08:00
@dingyaguang117 其实 dict 迭代器生成,删除其实就一天字节码指令,线程安全的逻辑并没有改变,a=a+1 应该是三条指令,加载、计算和保存,事实上除了计算,前两条指令不会有副作用,加法因为内存结构是指针操作,这么看其实这个其实也没有并发安全问题,但是大多数情况下这个操作需要加锁,估计是后面大概率就是判断语句,而这两之间就不是线程安全的了吧
sujin190
2021-10-20 12:46:34 +08:00
@dingyaguang117 好吧,纠正一下,数字加法指令会返回新的数字对象,所以保存这个字节码在多线程下这种情况就不是线程安全的了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/808500

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX