【问题标题】:Simple multithread for loop in PythonPython中的简单多线程for循环
【发布时间】:2016-12-15 19:41:25
【问题描述】:

我到处搜索,但没有找到任何使用多线程迭代循环的简单示例。

例如,我怎样才能多线程这个循环?

for item in range(0, 1000):
    print(item)

有没有办法把它切成4个线程,所以每个线程有250次迭代?

【问题讨论】:

    标签: python multithreading iteration


    【解决方案1】:

    从 Python 3.2 开始,concurrent.futures standard libraryconcurrently map a function across iterables 提供原语。由于mapfor 密切相关,因此可以轻松地将for 循环转换为多线程/多处理循环:

    from concurrent.futures import ThreadPoolExecutor
    
    with ThreadPoolExecutor() as executor:
        executor.map(print, range(0, 1000))
    

    【讨论】:

      【解决方案2】:

      最简单的方法是使用multiprocessing.dummy(使用线程而不是进程)和Pool

      import multiprocessing.dummy as mp 
      
      def do_print(s):
          print s
      
      if __name__=="__main__":
          p=mp.Pool(4)
          p.map(do_print,range(0,10)) # range(0,1000) if you want to replicate your example
          p.close()
          p.join()
      

      如果您想更好地利用多个 CPU,也许您也想尝试真正的多处理,但有一些警告和guidelines 需要遵循。

      Pool 的其他方法可能更适合您的需求 - 取决于您实际尝试做什么。

      【讨论】:

      • 谢谢!如果我需要将其他参数传递给do_print 函数怎么办?
      • 这取决于 - 使用 multiprocessing.dummy 应该没有问题,但如果你想确保你应该将参数放在可迭代中 - 例如使用 ziplist comprehensions
      • 出于某种原因,这段代码为我创建了大约 60 个(!)线程来迭代 range(0, 1000)(Python 3.5)...
      • @janbrohl:为避免不必要的临时性,您需要使用 Py3 的 zip(在 Py2 上,replace bad zip with good zip using from future_builtins import zip)或 generator expression,因此参数是惰性生成的(根据需要) 而不是急切地(延迟第一次调用的调度并浪费内存)。
      • @ForceBru:如果你用multiprocessing.dummy,那应该是不可能的;给出的Pool 构造函数只使用了四个工作线程。
      【解决方案3】:

      您必须手动进行拆分:

      import threading
      
      def ThFun(start, stop):
          for item in range(start, stop):
              print item
      
      for n in range(0, 1000, 100):
          stop = n + 100 if n + 100 <= 1000 else 1000
          threading.Thread(target = ThFun, args = (n, stop)).start()
      

      此代码使用多线程,这意味着所有内容都将在单个 Python 进程中运行(即只会启动一个 Python 解释器)。

      多处理,在另一个答案中讨论,意味着在几个 Python 解释器中运行一些代码(在几个 进程,而不是 线程)。这可能会利用所有可用的 CPU 内核,因此当您专注于代码的速度时(打印大量数字直到终端讨厌您!),这很有用,而不仅仅是并行处理。 1


      1. multiprocessing.dummy 原来是 a wrapper around the threading modulemultiprocessingmultiprocessing.dummy 具有相同的接口,但第一个模块使用 processes 进行并行处理,而后者 - 使用 threads

      【讨论】:

      • multiprocessing.dummy 实际上使用线程 - 编辑了我的答案以使其更清晰
      • multiprocessing.dummy 确实是 threading 模块的包装器,但 multiprocessing 本身的工作原理与答案的划掉部分中的描述完全相同。选择哪一个取决于一个人想要什么行为,代码是一样的(这是一件好事)。
      • @miraculixx,这就是为什么我决定不完全删除现在被划掉的部分:multiprocessingmultiprocessing.dummy 具有相似的接口,但是模块的选择会影响行为(线程与进程)。
      • @ForceBru 我明白了,问题是现在看起来你写的内容不正确,但事实并非如此,这可能会使寻找多处理的人感到困惑......multiprocessingmultiprocessing.dummy拥有完全相同的界面,这就是重点。
      • @miraculixx:不完全是,但足够接近,他们试图保持一致。例如multiprocessing.dummy 不小心省略了cpu_count 函数。
      猜你喜欢
      • 2014-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 2011-08-20
      • 1970-01-01
      • 2017-06-13
      • 2014-10-18
      • 2013-11-07
      相关资源
      最近更新 更多