问题标签 [gil]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
5162 浏览

python - 并行文件匹配,Python

我正在尝试改进扫描文件以查找恶意代码的脚本。我们在一个文件中有一个正则表达式模式列表,每行一个模式。这些正则表达式用于 grep,因为我们当前的实现基本上是一个 bash 脚本 find\grep 组合。bash 脚本在我的基准目录上需要 358 秒。我能够编写一个在 72 秒内完成此操作的 python 脚本,但我想改进更多。首先,我将发布基本代码,然后进行我尝试过的调整:

这显然是调试\丑陋的代码,千万不要介意 queue.put(-1),我稍后会清理它。一些缩进没有正确显示,特别是在 scanFile 中。

无论如何,我注意到了一些事情。使用 1、4 甚至 8 个线程(对于 xrange(0,???):) 中的扫描仪并没有什么不同。无论如何,我仍然得到〜72秒。我认为这是由于 python 的 GIL。

与制作一个巨大的正则表达式相反,我尝试将每一行(模式)作为一个 compilex RE 放在一个列表中,并在我的 scanfile 函数中遍历这个列表。这导致更长的执行时间。

为了避免 python 的 GIL,我尝试让每个线程分支到 grep,如下所示:

这导致更长的执行时间。

有关提高性能的任何建议。

:::::::::::::编辑::::::::

我还不能发布我自己的问题的答案,但是这里是对提出的几点的答案:

@David Nehme - 只是为了让人们知道我知道我有一百万个 queue.put(-1) 的事实

@Blender - 标记队列的底部。我的扫描仪线程一直在出队,直到它们到达底部的 -1(而 nextFile 不是 -1:)。处理器内核为 8,但由于 GIL 使用 1 个线程、4 个线程或 8 个线程并没有区别。产生 8 个子进程导致代码显着变慢(142 秒对 72 秒)

@ed - 是的,它和 find\grep 组合一样慢,实际上更慢,因为它不加选择地 greps 不需要的文件

@Ron - 无法升级,这必须是通用的。你认为这会加速 > 72 秒吗?bash grepper 执行 358 秒。我的 python 巨型 RE 方法使用 1-8 个线程执行 72 秒。包含 8 个线程(8 个子进程)的 popen 方法运行时间为 142 秒。到目前为止,巨大的 RE python only 方法显然是赢家

@intuted

这是我们当前 find\grep 组合的内容(不是我的脚本)。这很简单。里面有一些额外的东西,比如 ls,但没有什么会导致 5 倍的减速。即使 grep -r 稍微高效一点,5x 也是一个巨大的减速。

python代码效率更高,不知道为什么,但我实验测试了一下。我更喜欢在 python 中执行此操作。我已经用 python 实现了 5 倍的加速,我想让它加速。

:::::::::::::WINNER WINNER WINNER::::::::::::::::::

看起来我们有一个赢家。

intued 的 shell 脚本以 34 秒排名第二,但 @steveha 以 24 秒排名第一。由于我们的很多盒子没有python2.6,我不得不cx_freeze它。我可以编写一个 shell 脚本包装器来获取 tar 并解压缩它。不过,为了简单起见,我确实喜欢 intued。

谢谢大家的帮助,我现在有了一个高效的系统管理工具

0 投票
4 回答
2789 浏览

python - 发布 GIL 的成本是多少?

假设我有一个 C 扩展函数,它做的事情完全独立于 Python 解释器。有什么理由发布 GIL?

例如,是否有任何理由不编写这样的代码(除了诸如可读性和避免微优化之类的问题——这些问题很重要,但与我的问题并不真正相关)?

显然,这是一些性能可能无关紧要的琐碎代码。但是有什么性能原因不在这里发布 GIL 吗?还是应该只为更多 CPU 密集型代码发布 GIL?

0 投票
1 回答
4384 浏览

ruby - 我们可以在 Ruby 中并行运行多线程吗?

请让我知道是否有办法并行运行多线程。到目前为止,我所知道的是 Ruby 有一个全局解释器锁或全局 VM 锁,它阻止线程并行运行并同时实现。请让我知道一些详细的线程示例,以实际理解和验证线程是并行工作还是并发工作。

0 投票
4 回答
3349 浏览

python - 使用并行线程提高 Python 执行速度

假设我有这个示例代码:

我想通过使用线程来改善这段代码的执行时间(希望它有帮助,不是吗?)。我想让事情尽可能简单,所以基本上我想做的是创建两个同时工作的线程,分别计算foo1foo2.

我正在阅读一些关于线程的东西,但我发现它有点棘手,我不能为了做这么简单的事情而浪费太多时间。

0 投票
1 回答
485 浏览

python - boost::python 和回调驱动的执行

我在涉及 boost::python 和回调驱动执行的项目中遇到问题。

我的项目正在使用回调机制从 C++ 运行一些 python 代码。

只要导致我的回调执行的初始函数调用来自 python 解释器,一切都很好。例如:

唉,事情没那么简单。我的项目使用RtAudio与音频环境进行通信。RtAudio 的执行是回调驱动的:我给 RtAudio 一个回调函数,当我启动 RtAudio 时,每次需要计算声音时都会调用回调。

使用 RtAudio 的回调驱动执行时,只要我的代码尝试从 C++ 运行 python 回调,就会出现段错误。

要启动回调驱动的执行,我必须调用函数 start(),它是非阻塞的。这意味着回调驱动的执行发生在另一个线程中。

然后,当从 python 调用 start() 时,我正在创建另一个线程,分别访问 python 的执行环境。从我对python的GIL的一点了解来看,这样不好。

那么,我怎样才能让这个回调驱动的线程在不破坏一切的情况下运行 python 回调呢?

抱歉,我找不到将我的代码简化为我的问题的简短、功能齐全的示例的方法……问题就在那里

编辑

在查看了python 文档之后,我添加了几行代码,这些代码应该在非 python 创建的线程试图访问 python 环境时处理线程安全:

但我仍然遇到段错误。所以我通过 valgrind 运行它,这就是我得到的(减去 valgrind 总是从 python 解释器得到的奇怪的东西,这是“正常的”):

如果我做对了,我的回调函数正试图访问一个 NULL 指针,对吗?

编辑 2

好的,我正在发现这一切。从pthread 的文档中,看起来有一个对 的调用sem_post(sem),其中sem指向一个信号量。但它指向NULL。

现在,我怎样才能更准确地查明错误?

0 投票
4 回答
2698 浏览

python - Python线程什么时候快?

我们都知道GIL的可怕之处,我也看到了很多multiprocessing关于何时使用该模块的讨论,但我仍然不觉得我对 Python 中的线程有很好的直觉(专注于主要在 CPython 上)是正确的答案。

在哪些情况下 GIL 不是重大瓶颈?线程是最合适的答案的用例类型有哪些?

0 投票
1 回答
253 浏览

python - h5py 与另一个 HDF5 模块一起使用时导致死锁

我正在为使用 pthreads 和 HDF5 的 Python 编写 C++ 模块。我的模块在 H5F_ACC_EXCL 模式下创建 HDF5 文件,以便在文件已经存在时失败。在这种情况下,HDF5 会打印堆栈跟踪。该模块的 python C 接口函数在一个线程中执行,文件创建在另一个线程中进行。通常一切正常,但如果我使用我的模块在脚本中导入 h5py,系统就会陷入死锁。尝试创建文件的线程具有以下回溯:

[第 7 行通知我模块中的函数] 我发现导入 PyTables 不会导致此问题。任何有关解决此问题的帮助将不胜感激。

0 投票
1 回答
2939 浏览

c++ - SWIG C++ Python 多态性和多线程

我正在使用SWIG将第 3 方 C++ 包集成到 python 应用程序。该软件包通过网络连接到专有 API 并接收更新。整个流程是 python 实例化一个 C++ 对象,调用它的函数来设置它,然后等待更新。

我使用SWIG 的导向器功能实现了更新的回调机制,并且在从 python 或从 python 调用的 C++ 函数进行测试时,它运行良好。也就是说,我能够在 Python 中继承一个 C++ 类,从 C++ 调用它的虚函数,然后查看 Python 代码优先执行。

问题:
当我收到来自网络的更新时,我得到:

python27.dll调用回调函数时从内部抛出此异常。
我的怀疑是: 我违反了GIL
AFAIU,更新来自不同的线程并使用该线程调用 python 的代码。

在这一点上,我不知所措。SWIG 的导向器功能是否仅限于在 python 中启动的流(即来自 python 托管线程)?
我该如何规避这个?如何诱导从 C++ 到 python 的更新?甚至可以使用 SWIG 吗?
我应该使用完全不同的方法吗?

我愿意就此事提出任何建议......

0 投票
2 回答
792 浏览

python - 为什么 Python 的 math.factorial 不能很好地处理线程?

为什么 math.factorial 在线程中表现得如此奇怪?

这是一个示例,它创建了三个线程:

  • 只休眠一段时间的线程
  • 增加 int 一段时间的线程
  • 对大量数执行 math.factorial 的线程。

它调用start线程,然后join超时

sleep 和 spin 线程按预期工作并start立即返回,然后join等待超时。

另一方面,阶乘线程start直到运行到最后才返回!

这是 CentOS x64 上 Python 2.6.5 的输出:

我已经在 CentOS x64 上的 python 2.6.5 和 Windows x86 上的 2.7.2 上尝试过这个,并且阶乘线程不会从其中任何一个上的开始返回,直到线程完成执行。

我也在 Windows x86 上使用 PyPy 1.8.0 进行了尝试,结果略有不同。开始确实会立即返回,但是连接不会超时!

也尝试过 IronPython 2.7.1,它产生了预期的结果。

0 投票
0 回答
1367 浏览

python - 使python http服务器路由到不同的端口

这里有同样的问题,但答案是关于使用线程。我认为 GIL 不行。

我想制作许多不同的 HTTP 服务器(甚至不是 python),它们在不同的端口和不同的进程中运行。我想通过一些参数(例如 HTTP_HOST)将请求从端口 80 路由到它们。

我应该在服务器端(在路由器中)使用 HTTP 客户端来请求端口,还是有不同的方式?

我想做一些像 nginx 一样的事情,但我希望它动态改变。