V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  O5oz6z3  ›  全部回复第 2 页 / 共 5 页
回复总数  100
1  2  3  4  5  
@sujin190 #22
明白了,比起对付 GIL ,还是先提升单线程的性能更划算。
@hsfzxjy #13
感觉“抽象泄露”有点像是“依赖副作用”,不知道算不算是“隐式依赖 GIL”?
看来 GIL 即使真的能去掉,距离正式使用也很漫长。

@sujin190 #16
因为我也不懂具体细节,所以还想着把 GIL 版本的初始化方法用的函数和数据结构复制修改成细粒度锁模式也许行得通。
@v2exblog @ErwinCheung #10 #11
罚你们重看 /t/808955

@kasheemlew #14
我才发现我把 cython 和 c 扩展搞混了。

@wangyzj #19
我也不知道有没有必要,不过 GIL 好像有 CPU 颠簸之类的其他副作用……
@msg7086 #8
理论可行性应该是成本的前提吧?理论不可行也就不需要考虑成本了……

原来如此,看来多数情况下还是 c 扩展简单粗暴……

看到一篇介绍 wiki.python.org/moin/GlobalInterpreterLock ,看来在目前的版本设计实现细粒度的 GIL 可能还是很有难度和很大工程量。(维护两套代码可能也很麻烦)
@ysc3839 #6
也就是和#2 楼说的一样,不用“命令行开关”,干脆用“编译时开关”,将 python 编译成细粒度 GIL 的可执行文件?
感觉也可行,也就是开关的位置其实不太重要。
那么问题就变成了:“Python 为什么不提供两种 GIL 对应的两套可执行文件?”
@msg7086 #2
我的意思就是,如果暂时不考虑成本,这个方案理论上可行吗?
况且细粒度 GIL 似乎(很久)以前有人实现过,参考上面 #3 的链接。

至于你所说的“运行时判断”,如果我没理解错的话,是指每次解释执行字节码指令的时候,判断使用哪种 GIL ?我不是这个意思,我是指上面提到的根据命令行开关(例如`python --threads ...`)调用对应的“入口函数”(`Py_Initialize`/`Py_Initialize_threads`)。

C 扩展这点也参考上面 #3 。虽然 CPU 密集确实应该用 C 扩展来解决,但 C 扩展的缺点是,需要编译(和需要写 C 语言……)。

@ysc3839 #4
python 的编译时开关?这个我不知道是什么……
@sujin190 #1
@msg7086 #2
关于命令行开关,可能我说得不够清晰。我不了解 CPython ,以下举的例子可能不恰当:打个比方的话就是“单线程模式”用 `Py_Initialize()`,用普通的粗粒度 GIL 。“多线程模式”用 `Py_Initialize_threads_mode()`,采用细粒度的 GIL 优化多线程性能。

更具体的话就是指 docs.python.org/zh-cn/3/faq/library.html#can-t-we-get-rid-of-the-global-interpreter-lock 文档里提到的那个细粒度 GIL 。既然能够实现细粒度 GIL ,那么在命令行启动解释器的时候选择用哪一种 GIL ,看上去应该很容易实现?

至于那些已经存在的 C 扩展,虽然我也不太懂 C 扩展,但我猜如果本来就隐式或显式依赖 GIL ,那么似乎本来就不适合多线程并行?
而且“多线程细粒度 GIL”是可选的,如果不兼容那么回退到原来的粗粒度 GIL 就是了。

虽然我也不知道去掉 GIL 有什么意义,不过也许有利于并行计算?

至于 python 其他没有 GIL 的实现,老实说我没用过,而且看上去版本更新缓慢……
2021-10-23 22:34:26 +08:00
回复了 ChrisFreeMan 创建的主题 生活 每日负:我为什么讨厌亲戚,以及拒绝和他们谈论我的私事
高情商:你有没有想过群居动物为了合群,需要改变自己来融入圈子?
低情商:你没有想过,你只在乎你自己
你来找安慰,他来找乐子,我来找存在感,大家都有无限的可能性
感觉和这个帖子很像 /t/806979
顺便想到两种可能:1 、久坐 2 、肚子饿了 3 、左右脑交替使用?
2021-10-13 15:07:12 +08:00
回复了 NoUltimate 创建的主题 Apple 想请教一下你们怎么管理苹果相册
没看懂在争啥,不就是分治与 AI 吗?文件夹(树形)更有条理,可以按自己口味清晰地分门别类,不过很费时费力。图库(扁平)更便利,不过只能按机器的口味来分类照片,而且图片全部混合在一起难以手动整理。
两种思路:1 、反正整理完也是吃灰 2 、分类问题就是空间问题,空间问题就是成本问题,成本问题就是钱的问题,钱的问题不是问题!
2021-10-12 20:02:15 +08:00
回复了 Linchstein 创建的主题 随想 今年春天,我放生了一条鲨鱼
鲨鱼放水缸,小鱼已为汁,已与家父谈,欲载河中弃,若非已放生,香煎鱼翅鳍!《弃布施·月半武》
2021-09-28 06:26:55 +08:00
回复了 MiketsuSmasher 创建的主题 Python Python 类方法的装饰器问题
原因是在类定义内使用 valid_before_logout 时,就是个普通函数,不是实例方法,所以会缺少 self 。就和 cls.method() 是一样的,会报错缺少 self 。一开始我也以为装饰成静态方法或类方法就解决了,没想到这种方法不兼容直接调用。
想到一个简单的思路兼容两种情况,不过没有试验过:
def valid_before_logout(self, func=None):
... func = func or self
... #...
2021-09-26 10:53:35 +08:00
回复了 abersheeran 创建的主题 Python 求一个获取 lambda 对象源代码的方法
@abersheeran #15 我指的是 __code__.co_code 字节码,是从那篇文章中学来的,虽然我也不确定这个字节码比较是否可靠。顺便写了两个 demo 。
简单的情况:
source_text = inspect.getsourcelines(lambda_func)[0][0]
source_ast = ast.parse(source_text)
lambda_node = next((node for node in ast.walk(source_ast) if isinstance(node, ast.Lambda)), None)
lambda_text = ast.unparse(lambda_node)
复杂的情况:
text = 'lambda' + inspect.getsource(lambda_func).partition('lambda')[2].rstrip()
while text:
... try:
... ... tree = ast.parse('({})'.format(text))
... ... srcs = [ast.unparse(node) for node in ast.walk(tree) if isinstance(node, ast.Lambda)]
... ... break
... except SyntaxError:
... ... text = text[:-1]
test = lambda src: compile(src,'','eval').co_consts[0].co_code==lambda_func.__code__.co_code
hits = list(filter(test, srcs))
2021-09-26 10:29:52 +08:00
回复了 abersheeran 创建的主题 Python 求一个获取 lambda 对象源代码的方法
本质上也许是寻找一个表达式的源码位置:
1. lambda 有多少行?
2. 同一行里有几个 lambda ?
3. 是否嵌套 lambda ?
4. 是否有'lambda'字面字符串?
http://xion .io/post/code/python-get-lambda-code.html
看到这篇文章和#3 楼的实现,想到一个未验证的思路:对 inspect.getsource() 获取的源码进行修剪并编译成 ast,遍历 ast 提取所有 lambda 节点,用 Python3.9 的 ast.unparse() 获取近似的源码,用 co_code 判断源码编译后是否等价。
跑个题,其他人未必随便吧,不是古语云台上十分钟
2021-09-25 08:07:20 +08:00
回复了 Renco 创建的主题 职场话题 怎么样区分努力和内卷
内斗内卷外斗外卷?
2021-09-25 06:53:40 +08:00
回复了 MiketsuSmasher 创建的主题 Python [ Python ]如何取回生成器的返回值
基本原理已经被楼上说完了,至于你的需求可以很容易想到一个简单的实现,不知道有没有现成的:
class wrapiter:
... def __init__(self, _iter):
... ... self.iter = iter(_iter)
... ... self.val = None
... def __iter__(self):
... ... return self
... def __next__(self):
... ... try:
... ... ... return next(self.iter)
... ... except StopIteration as e:
... ... ... self.val = e.value
... ... ... raise

it = wrapiter(range(9))
print([x for x in it])
print(it.val)
1  2  3  4  5  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3438 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 29ms · UTC 11:41 · PVG 19:41 · LAX 03:41 · JFK 06:41
Developed with CodeLauncher
♥ Do have faith in what you're doing.