【问题标题】:Threading in python using a generator使用生成器在 python 中进行线程化
【发布时间】:2015-12-15 18:24:51
【问题描述】:

我正在创建一种算法,该算法使用生成器对象蛮力搜索 3x3 矩阵的条件以创建所有可能的组合。目前,在单个线程上运行它所需的时间将花费大量时间,但是我可以访问具有许多内核 (64) 的计算机,因此将其线程化为具有至少 20 个线程将是非常可行的选项。

但是,我不能简单地将生成器对象转换为列表并将列表分成大小相等的块。存储列表列表所需的 RAM 量太高了。

我的单线程方法(为问题简化)如下:

def permute(xs, low=0):
    if low + 1 >= len(xs):
        yield xs
    else:
        for p in permute(xs, low + 1):
            yield p     
        for i in range(low + 1, len(xs)):       
            xs[low], xs[i] = xs[i], xs[low]
            for p in permute(xs, low + 1):
                yield p     
            xs[low], xs[i] = xs[i], xs[low]

generator_obj = permute(range(9))
for l in generator_obj:
    search_conditions(l)

什么是线程化的好方法?

【问题讨论】:

  • 线程不会帮助你。 Python 中的多线程很糟糕,因为 Python 的标准实现有各种线程不友好的设计,并且需要一个全局解释器锁来确保同时执行的线程不会搞砸解释器内部。这意味着它几乎是一次一个线程。你可以试试 multiprocessing 模块,它使用多个完整的 Python 进程来绕过锁,或者你可以试试更线程友好的语言。
  • 尝试使用队列进行多处理。见link
  • @user2357112 今天晚上我会看看服务器上安装了哪些其他编程语言供我使用。我想你链接错了页面,taesu。你的意思是this one

标签: python multithreading generator python-multithreading brute-force


【解决方案1】:
  1. 即使你有多个线程,它们仍然会在同一个进程中,只会在一个内核上执行。

  2. 与其将数据分成固定数量的相等块,不如动态创建一组批次?例如,您可以

    • 使用生成器创建要处理的项目列表,该列表足够小以避免填满 RAM 的任何危险,
    • 使用以下建议: https://stackoverflow.com/a/1269055/3366796
    • 或使用picklemsgpack 或数据库将列表列表保存到磁盘
    • 然后,使用单独的脚本,使用subprocess.Popen 处理每个批次并将结果写回磁盘
    • 等待进程完成,然后让另一个例程汇总结果

这种方法将利用多核系统的强大功能,但应考虑确保磁盘不会成为瓶颈。

编辑:我会试试这个 -> http://www.dabeaz.com/coroutines/coprocess.py

【讨论】:

  • 关于奇异核心问题的要点。我也会尝试您的建议,但我完全忘记了 itertools,它与多个 Python 进程结合使用应该使我能够以最小的瓶颈利用适当的多线程。
猜你喜欢
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2015-06-23
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 2021-08-29
相关资源
最近更新 更多