Python 中 有 CAS 的实现吗
Google 了一下 "Python" "CAS",只是搜到了一些关于 GIL 的 ATOMIC 操作。
但是觉得 Python 的 Lock() 又有点沉,有大佬知道有没有类似 CAS 的轻量级实现吗?
统一回复了,我是使用一个标记变量 + 短代码实现类似 CAS 的效果,在 for _ in range(1000000):加法中四个线程大概用时 5 秒,并保证了总数是 4000000 。
而直接使用 Lock 耗时是 17 秒。
GIL 在 Python2 中是 1000 行字节码切换线程,Python3 中是 15 毫秒切换线程。list.pop 这种 C 调用是 atomic 的。
等一个莫名其妙喷 java 的
不过也有可能没有,因为 cas 不多学点 java 还真不知道是什么
java 被喷不是语言的问题,正是因为你这种 java boy 太多,让我等羞于为伍,说自己写过几年 java 都心惊胆战怕被人误认为你们。
cas 和 java 又有什么关系了?人家实现 cas 的时候还没现代操作系统呢,你家 jvm 都没地方跑谢谢。
#2 "等一个莫名其妙喷 java 的"你可真会咬钩
我没说 cas 跟 java 有关系,只是某些喷 java 的喜欢带上
同理设计模式也跟 java 没啥关系,还不是天天喷 java 设计模式滥用?
还羞与为伍,笑死
没发现有, python 单进程的, 直接用 Lock().
???为什么喷 Java 要带上 CAS 啊,你说设计模式我还能理解
没有而且不需要。因为 GIL 直接保证了同步。
GIL 不等于线程安全,GIL 不保证线程变量同步。
#5 设计模式不是 java 独有的,也不是 java 发明
cas 不是 java 独有的,也不是 java 发明
设计模式跟语言无关 , 基本上有点名气的开源项目里面都是设计模式的影子在里面
stackoverflow.com/questions/45802491/compare-and-swap-instruction-in-python
Python 一般我都用 Lock() 来确保类似 i += 1 这种操作的原子性, 之前查找资料有实现原子性的一些库, 不过没用过.
Python 的 CAS 将是一场灾难啊。。。GIL 把一个忙等待的线程切了进来。。。
#6 保证不了,不说 if 和赋值之间会不会切线程,就是赋值也不一定安全
CAS 是 cpu 指令级提供的冲突处理的,python 一个+1 操作都好多条 cpu 指令了,这个在 python 层面上来看已经毫无意义了吧
比较难想象 Python 怎么 CAS,l.a = b 不是原子的,这要变成三条字节码,两个 LOAD_NAME 和一个 STORE_NAME 。
如果直接用 a = b,那你压根拿不到 a 的结果,因为 Python 没有指针,函数里赋值过去就没了。
如果用 nonlocal global 去修复拿结果的问题,那就没办法做到无副作用,而且这只是换了个 name,对象所在的内存还是没有变化。
综上所述,建议直接 threading.Lock,不会有人上了 Python 还扣这个锁的性能吧?大可不必啊
在 CPython 虚拟机里,是按照字节码来逐个执行的。对于一个单进程 CPython 程序来说,字节码层面的原子性就足够了,CPU 级别的才是没有意义。
赋值都不安全?看来我孤陋寡闻了。233
#16 但这个实现没啥现实意义啊,CPU 级 CAS 的价值是在多核中,CAS 可以通过占用少量 CPU 时间来换取通过更重度的锁来导致线程休眠切换调度的问题,同时还可以最大限度保护内核缓存失效的问题,毕竟现代 cpu 和缓存速度太快了,但是你在 Python 层面做一个这东西似乎啥都没解决吧,没啥意义确实没啥提供的必要
为了 CAS 而上 CAS 的人还是挺多的,毕竟是吹嘘的资本,尽管在他们手里几乎解决不了任何实际问题。
#17 最简单一条赋值语句一般有三条 bytecode 组成,单条 bytecode 是线程安全的,多条之间不是,你可以用 dis 显示下编译出的 bytecode 就知道了
#19 确实了,Python 上 CAS 确实是为了 CAS 而 CAS 了,毕竟 GIL 限制了,不过如果你搞个扩展释放掉 GIL 的话就可以搞了
看完讨论。。我以为是 CAS 单点登录,我还纳闷这有啥好讨论的。。。落伍了落伍了
搜 atomic 好像有几个,试试看?
我还以为是 computer algebra system,差点开始安利 SageMath (
搞扩展那也是别的语言了,一般是 C,C 的 CAS 这资料还不到处都是,可以说跟 Python 一点关系都没有了。哈哈哈。
docs.python.org/3.10/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe,但是这里面说 x=y,和 x.field=y 是 atomic 的。(内置类型限定)
此贴前三楼以自己为示范展示了不加控制的人类本性
点击来之前以为是计算机代数系统
我第一眼也以为是说计算机代数系统
设计模式的影子就不叫设计模式。设计模式的全部想法都是在(拙劣、错误且反思考地)尝试提取习惯性操作并为之取个名字。
你这就好比大多数语言给 a=1 取个名字叫「赋值」,然后说『( Haskell 的) let a=1 in ... 有赋值的影子』,这说明你被词汇和词义限制住了思想。
据我所知,Python 只有.append() 是 aotmic 的,有点小坑但是有 GIL 了
恕我孤陋寡闻,python 确保线程安全的一般手段应该就是 threading.Lock,还真没见过其他方式
有毒. 楼主完全没提 java 你 1L 莫名其妙来个喷 Java?
不是,你就好好学学啥是 GIL 。threading.Lock 主要是保证 PythonVM 外的临界区的。
你可以直接说你想表达的东西
#34 你可以直接说你想表达的东西
1 楼这种真的是毒瘤,立个靶子自己打,败坏社区氛围,引战
真的吗?有了 GIL 什么都不用考虑了?
Python2 中 GIL 是运行 1000 行字节码,然后切换线程,Python3 是 15 毫秒切换线程。GIL 跟线程安全根本毫无关系,除非你能精准的控制字节码的数量。其次就是,dict.append,list.pop 这种 C 语言调用实现,是 Atomic 的。
dict 没有 append,说错了,remove
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)
#26 一个赋值语句两条字节码组成,以 Python 的内存结构来说,其实就算被拆开其实越不会有副作用,所以认为是原子操作其实也没有啥问题
#39 Python 的 GIL 就是用来保证内部数据结构线程安全的,否则直接删掉 GIL 就是了啊,所以肯定必须要求是单条字节码完整执行完成才能切换,不可能像操作系统线程一样时间一到啥都不管就直接切换吧,否则 Python 内部自身的数据结构都有可能被破坏了,从这一点上来说,GIL 保证单条字节码的完整性,确实提供了大量线程安全的操作,比如赋值,不能说毫无关系吧
嗯嗯,毫无关系确实不至于,对象内部的线程安全确实没错,不过问题是只有 CPython 存在 GIL,JPython 是没有的。
GIL 是用来保证对象内部线程安全怎么理解,什么是内部对象,那些场景线程安全?
应该是只有单字节码的操作才能保证线程安全。a=a+1 应该都不是
GIL 锁不能完全解决线程安全问题,举个例子:一个线程遍历 dict,另一个删除。线程安全问题不仅是一行语句的安全
晕...我上面不是说了吗...保证对象的 pop,append 线程安全,内部的,不是两个线程同时操作。我没说两个线程同时操作线程安全。因为 pop 和 append 是 C 语言调用,C 语言调用的都是 ATOMIC 的。
人家说的是内部数据结构,是 pop,remove 等内部的操作,不是让你两个线程同时操作的...理解错了吧兄弟
Python 解释器也需要用内存,也有数据结构啊,编译,创建类,模块导入,线程创建,文件操作,套接字这些底层也是用 GIL 保证线程安全的吧
如题,现在是两块 18T 组的 RAID1 ,现在想购置新硬盘,原本想 RAID1 升级 RAID5 ,看到了好多 RAID5 炸盘后重建炸裂的问题,我的数据没什么重要的,大多…
国内外都在加速中 最近强制用 Google Lens 替换原来的搜图,明年 Chrome 也要求上架 MV3 扩展 Google 真是越来越恶心 但就像微信一样已经深度捆绑不得…
题目最好简单一些,但是还不能从 GPT 直接询问得到答案,头疼。 不是面试也不是考试,是培训。在培训过程中我也会演示如何用 GPT 来辅助编程。但是我需要给学员出一些更有挑战…
合速度