我知道cPython有一个GIL,因此如果不使用多处理模块,您的脚本就无法在多个内核上运行。但有没有什么可以阻止内置功能,如使用多核进行排序?我不明白cPython的结构,但我认为我问的问题是'内置函数,比如sort,any和list comprehensions实际上是在GIL之下吗?
答案 0 :(得分:5)
cPython GIL只允许单个线程在进程内运行字节码 - 它与非抽象的CPU无关。
也就是说,截至目前,除非您正在调用某些内容来分叉/使用多个进程,或者您的操作系统/硬件正在捕获调用并为您执行此操作(极不可能),您将看到所有操作都发生在一个CPU核心。
在C中实现的内置函数发生在GIL"下面。因为他们更直接地调用底层API,但是在GIL中放置参数和数据,因为你正在使用字节码进行读写。
顺便说一句,如果您想更好地了解cPython与其主机的关系,我建议使用以下high-level official overview和/或the PDF slides and the playground that I wrote for a conference。
答案 1 :(得分:2)
您提及的所有功能都不会自动并行化。一般来说,在大多数语言中,静默生成线程被认为是不好的形式(这种情况正在改变,但它仍然只能在纯函数式语言中看到,其中线程安全性在设计中被烘焙);产生大量线程而不发出警告是当用户尝试启动自己的线程并由于运行线程太多而导致出现暂时性错误时,如何获得神秘错误。因此,即使GIL不是问题,这样做也没有意义。
也就是说,GIL可以保护翻译内部,并且涵盖了操纵引用计数的任何情况,这是不断的;除了罕见的例外,它不可能在PyObject*
上进行任何有意义的工作(这是所有Python级别类型在C中表示的),并保持GIL。通常,Python内置函数仅释放GIL以进行阻塞操作(I / O,等待锁等);它仅适用于GIL发布正常的第三方C扩展(和ctypes
),因为在这些情况下,它们将PyObject
完全转换为C级类型,现在释放GIL没有引用引用计数或其他内部,执行昂贵的工作,重新获取GIL,并将结果从C级别类型转换回Python级别对象。