我经常看到有人说GIL是根据Python解释器(甚至在stackoverflow上).
但是我在源代码中看到的似乎是GIL是一个全局变量,因此每个python进程中的所有解释器都有一个GIL.我知道他们这样做是因为没有像lua或TCL那样传递的解释器对象,它在开始时设计得不好.线程本地存储似乎不适合python人员使用.
它是否正确?我简要介绍了我在这个项目中使用的2.4版本.
如果在以后的版本中有所改变,特别是在3.0版本中?
我刚刚看到Unladen Swallow的这一部分文档出现在Hacker News上.基本上,谷歌工程师说他们对删除GIL并不乐观.然而,似乎有关于垃圾收集器的讨论穿插在这个关于GIL的讨论中.有人可以向我解释这种关系吗?
我试图找到一个函数,告诉我当前线程是否具有全局解释器锁.
Python/C-API文档似乎不包含这样的函数.
我目前的解决方案是PyGILState_Ensure()在释放之前获取锁定,PyEval_SaveThread而不是尝试释放当前线程未获取的锁定.
(顺便说一下,"发出致命错误"是什么意思?)
这个问题的背景:我有一个嵌入Python的多线程应用程序.如果线程在没有释放锁定的情况下关闭(可能由于崩溃而发生),则其他线程将无法再运行.因此,当清理/关闭线程时,我想检查该线程是否保持锁定并在这种情况下释放它.
提前谢谢你的答案!
我只是在寻找这个新的实现,我使用python 2.7,我必须安装它,所以如果我使用它,我会忘记CPython上的GIL这个词?
我有一本字典,
my_dict = {'a':[1,2,3], 'b':[4,5] , 'c':[7,1,2])
Run Code Online (Sandbox Code Playgroud)
我想在Cython nogil函数中使用这个字典.所以,我试图宣布它为
cdef dict cy_dict = my_dict
Run Code Online (Sandbox Code Playgroud)
到目前为止这个阶段很好.
现在我需要迭代my_dict的键,如果值在列表中,则迭代它.在Python中,它很容易如下:
for key in my_dict:
if isinstance(my_dict[key], (list, tuple)):
###### Iterate over the value of the list or tuple
for value in list:
## Do some over operation.
Run Code Online (Sandbox Code Playgroud)
但是,在Cython中,我想在nogil中实现相同的功能.因为,在nogil中不允许python对象,我都被困在这里.
with nogil:
#### same implementation of the same in Cython
Run Code Online (Sandbox Code Playgroud)
有人可以帮帮我吗?
期待在python中编写一个小的web爬虫.我开始研究将其编写为多线程脚本,一个线程下载池和一个池处理结果.由于GIL它实际上会同时下载吗?GIL如何影响网络爬虫?每个线程都会从套接字中选择一些数据,然后转到下一个线程,让它从套接字中选择一些数据等等.
基本上我要问的是在python中做一个多线程爬虫真的会给我带来很多性能vs单线程?
谢谢!
当调用通过Python subprocess模块花费相对较长时间的linux二进制文件时,这会释放GIL吗?
我想并行化一些从命令行调用二进制程序的代码.是否更好地使用线程(通过threading和a multiprocessing.pool.ThreadPool)或multiprocessing?我的假设是,如果subprocess发布GIL,那么选择该threading选项会更好.
我正在尝试决定是否应该使用多处理或线程,并且我已经学习了一些有关Global Interpreter Lock的有趣内容.在这篇不错的博文中,似乎多线程不适合繁忙的任务.但是,我还了解到一些功能,如I/O或numpy,不受GIL的影响.
任何人都可以解释为什么,以及我如何能够找出我的(可能非常重的)代码是否适合多线程?
PyGILState_Ensure()pybind11 是否以某种方式神奇地完成了和的工作PyGILState_Release()?如果没有,我该怎么做?
关于使用 pybind11 将 python 函数作为回调传递给 C++有 很多 问题,但我还没有找到一个解释如何使用 pybind11 的 GIL 的问题。
\n文档中关于 GIL 的说明非常清楚:
\n\n\n[...] 但是,当从 C 创建线程时(例如由具有自己的线程管理的第三方库),它们不\xe2\x80\x99t 保存 GIL,也不存在它们的线程状态结构。
\n如果您需要从这些线程调用Python代码(通常这将是上述第三方库提供的回调API的一部分),您必须首先通过创建线程状态数据结构向解释器注册这些线程,然后获取GIL,最后存储它们的线程状态指针,然后才能开始使用 Python/C API。
\n
我可以轻松绑定一个需要回调的 C++ 函数:
\npy::class_<SomeApi> some_api(m, "SomeApi"); \nsome_api\n .def(py::init<>())\n .def("mode", &SomeApi::subscribe_mode, "Subscribe to \'mode\' updates.");\nRun Code Online (Sandbox Code Playgroud)\n相应的 C++ 函数类似于:
\nvoid subscribe_mode(const std::function<void(Mode mode)>& mode_callback);\nRun Code Online (Sandbox Code Playgroud)\n但是因为 pybind11 无法了解我的 C++ 实现中发生的线程,所以我认为它无法为我处理 GIL。因此,如果mode_callback由从 C++ 创建的线程调用,这是否意味着我应该为每个调用编写一个包装SomeApi::subscribe_mode器? …
我试图理解为什么在并行线程中运行多个解析器不会加速解析HTML.一个线程完成100个任务的速度是两个线程的两倍,每个线程有50个任务.
这是我的代码:
from lxml.html import fromstring
import time
from threading import Thread
try:
from urllib import urlopen
except ImportError:
from urllib.request import urlopen
DATA = urlopen('http://lxml.de/FAQ.html').read()
def func(number):
for x in range(number):
fromstring(DATA)
print('Testing one thread (100 job per thread)')
start = time.time()
t1 = Thread(target=func, args=[100])
t1.start()
t1.join()
elapsed = time.time() - start
print('Time: %.5f' % elapsed)
print('Testing two threads (50 jobs per thread)')
start = time.time()
t1 = Thread(target=func, args=[50])
t2 = Thread(target=func, args=[50])
t1.start()
t2.start()
t1.join()
t2.join() …Run Code Online (Sandbox Code Playgroud) gil ×10
python ×10
cython ×1
future ×1
lxml ×1
numpy ×1
performance ×1
pybind11 ×1
subprocess ×1