【问题标题】:Python multithreading function argumentPython多线程函数参数
【发布时间】:2019-09-17 07:15:50
【问题描述】:

我正在编写一些多线程代码并且在我的代码中存在语法问题,并且发现代码不是并行执行而是顺序执行。我修复了将参数作为单独列表传递给函数的问题,而不是将其作为参数传递给函数,但我不知道为什么 python 会这样,也找不到它的文档。有人知道为什么吗?

import time
from concurrent.futures import ThreadPoolExecutor

def do_work(i):
    print("{} {} - Command started".format(i, time.time()))
    time.sleep(1)

count = 0
executor = ThreadPoolExecutor(max_workers=2)
while count < 5:
    print("Starting work")
    executor.submit(do_work(count))
    print("Work submitted")
    count += 1

修复这条线使其平行。

    executor.submit(do_work, count)

【问题讨论】:

    标签: python concurrency


    【解决方案1】:

    您告诉 Python 执行函数 do_work(),然后将该函数返回的任何内容传递给 executor.do_work()

    executor.submit(do_work(count))
    

    如果您使用变量来保存do_work() 的结果,您可能会更容易看到这一点。以下在功能上等同于上述:

    do_work_result = do_work(count)
    executor.submit(do_work_result)
    

    在 Python 中,函数是一等对象;仅使用名称 do_work 您正在引用函数对象。只有将(...) 添加到生成函数对象(或其他可调用对象类型)的表达式才会导致执行某些内容。

    在表格中

    executor.submit(do_work, count)
    

    您确实调用该函数。您将函数对象本身作为第一个参数传入,count 作为第二个参数传入。 executor.submit() 函数接受可调用对象及其参数,然后稍后使用提供的参数并行运行这些函数。

    这允许ThreadPoolExecutor 获取该函数引用和单个参数,并且只在新线程中调用该函数,稍后

    因为您首先调用该函数,所以您必须等待每个函数首先完成,因为您在添加之前按顺序调用它。而且因为函数返回None,您将那些None 引用添加到executor.submit(),并且会看到TypeError 异常稍后告诉你'NoneType' object is not callable。发生这种情况是因为线程池执行程序尝试使用 None(),这不起作用,因为确实,None 不是可调用的。

    在底层,库本质上是这样做的:

    def submit(self, fn, *args, **kwargs):
        # record the function to be called as a work item, with other information
        w = _WorkItem(..., fn, args, kwargs)
        self._work_queue.put(w)
    

    所以引用函数和参数的工作项被添加到队列中。创建工作线程,再次从队列中获取项目(在另一个线程或子进程中),调用 _WorkItem.run() 方法,该方法运行您的函数:

    result = self.fn(*self.args, **self.kwargs)
    

    然后使用(...) 调用语法。因为有多个线程,所以代码是并发执行的。

    您确实想了解纯 Python 代码如何不能并行运行,只能同时运行:Does Python support multithreading? Can it speed up execution time?

    你的do_work() 函数只运行“更快”,因为time.sleep() 不需要做任何实际的工作,除了告诉内核不要给执行睡眠的线程任何执行时间,对于请求多少时间。你最终会得到一堆都睡着的线程。如果您的工作人员必须执行 Python 指令,那么并发或顺序运行这些函数所花费的总时间不会有太大差异。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      相关资源
      最近更新 更多