Python内部是如何存储GC引用变量的计数的?

这段时间一直在想一个问题,为什么Python有了GIL依然还要对变量加锁。Google的过程中查看一些东西,有了新的困惑。

一个说法说Python内部保存了一个用户空间和一个内核空间。用户空间通常就是我们自己编写程序的对象(变量)。而GIL控制的就是内核空间,内核空间保存了比如GC对于变量的计数,而内核空间是由GIL控制的。

引用知乎的一个回答请问下面说的这段话的意思中的维护的这个字典是不是就是上面所说的内核空间?难道是globals()查出的字典,应该不是,字典中好像找不到变量的引用?

因为, 有了GIL, 提供并发就变得很容易. 解释器只要计算每个线程的运行时间就好了,时间一到, 将这个线程冻结, 内存管理很简单.等等, 你还是没解释, 如果我已经给线程上了锁, 为什么还是要被GIL限制?一向符合人类直觉的Python, 有个很反直觉的机制.Py的变量a其实不是C系编译语言的变量.Python维护着一个字典, 储存着a和对应数值的指针.用某黑Python的大牛的话说, Python企图用字典装下世界..如果变成真多线程对于这个字典的维护将会很复杂.多个线程真正同时操作一个字典, Python引以为傲的字典性能, 估计就没那么强了.就是说, Python字典的性能强大,是建立在线程不安全的基础上.而字典在Python中的位置又是如此重要, 一个缓慢的字典, 会严重拖慢Python的解释速度.多线程操作多个独立字典. 那样还是要同步.那为什么不采用多进程呢? 这就社区主流的看法.虽然理论上线程成本更低, 但是那样代码就改成面目全非了..

ps: 对于上面这段引用,拜托大神解释一下,感觉作者不是说的那么直接!

我的困惑

  1. Python内部是如何存储GC引用变量的计数的,是装到一个dict,而且这个dict是存放到kernel space而不是user space吗?

  2. Python维护着一个字典, 储存着a和对应数值的指针.用某黑Python的大牛的话说, Python企图用字典装下世界。这句话怎么理解?

clipboard.png

回答:

这个比较容易理解,GIL保证python byte code在进程内同时只有一个native thread在运
行。但byte code自身的逻辑仍然需要加锁/互斥等保证线程可重入,因为byte code运行
过程中任意点都可能被打断并切换到另外的线程。

举个简单的例子:
一段计数器的代码:
// Step 1
counter = get_counter()
// Step 2
counter += 1
// Step 3
set_counter(counter)

假设初始Counter为0,在不做任何同步的情况下两个线程同时执行这段Python代码,
期望结果应该是两个线程都做了计数,最终Counter应该为2:

但由于没有进行加锁/互斥导致执行情形如下:

  1. 线程A执行完Step1时取得counter为0,这是切换到线程B

  2. 线程B顺利执行完Step1,2,3,现在Counter为1,然后切换到A

  3. 线程A继续执行完Step2得到counter为1,然后Step3设置Counter为1。

最终结果为1.

以上是 Python内部是如何存储GC引用变量的计数的? 的全部内容, 来源链接: utcz.com/p/194683.html

回到顶部