【问题标题】:return of ThreadPoolExecutor to array of tasks将 ThreadPoolExecutor 返回到任务数组
【发布时间】:2018-09-13 13:25:49
【问题描述】:

下面是我从https://tutorialedge.net/python/concurrency/python-threadpoolexecutor-tutorial/得到的示例代码

from concurrent.futures import ThreadPoolExecutor
import threading
import random

taskarr = []

def task(n,c):
    print("Executing our Task = {} and {}".format(n,c))
    print("Task Executed {}".format(threading.current_thread()))

def main():
    executor = ThreadPoolExecutor(max_workers=3)
    task1 = executor.submit(task(1,'A'))
    task2 = executor.submit(task(2,'B'))

if __name__ == '__main__':
    main()

在这里,如果 executor.submit 返回到简单变量 task1,它可以工作。但我的要求是将它返回到一个数组。所以当我这样做时, taskarr[0] = executor.submit(task(1,'A')) 它抛出错误,

TypeError: 'function' object does not support item assignment

【问题讨论】:

  • taskarr[0] = executor.submit(task(1,'A')) 应该触发一个IndexError,如果你做了task[0] = executor.submit(task(1,'A')) ,描述的TypeError 将被引发。为什么不用taskarr.append
  • 这在这方面帮助了我:pymotw.com/3/concurrent.futures

标签: python threadpoolexecutor


【解决方案1】:

我无法复制您的TypeError;显然,您还有一些没有向我们展示的代码。正如rocksportrocker 在他们的comment 中指出的那样,您不能将值分配给尚不存在的索引,就像您尝试将从executor.submit() 返回的未来分配给空列表typearr 的索引0 一样。这将引发提到的IndexError

但是,我可以生成一些 TypeError,这是因为您错误地调用了 submit

Executor documentation 将参数 fn 定义为可调用对象,例如一个函数。现在,当你像你一样拨打submit 时:

executor.submit(task(1,'A'))

task(1,'A') 在您的主线程中执行,然后将其返回值(在您的情况下为None)传递给池线程。然后池线程尝试执行None(1, 'A') 并引发TypeError: 'NoneType' object is not callable,您看不到它,因为它在未来被包装。如果你打电话给task1.result(),你会看到它。

这意味着,执行任务的是您的主线程,而不是池线程,正如您在 task 中的第二个打印语句中应该看到的那样:

Task Executed <_MainThread(MainThread, started 11064)>

为了让您的池线程完成工作,您需要将函数对象task 传递给executor.submit,如下所示:

taskarr = []

def task(n,c):
    print("Executing our Task = {} and {}".format(n,c))
    time.sleep(3)  # added this to make sure that two different threads from the pool get a task
    print("Task Executed {}".format(threading.current_thread()))

def main():
    executor = ThreadPoolExecutor(max_workers=3)
    taskarr.append(executor.submit(task, 1,'A'))
    taskarr.append(executor.submit(task, 2,'B'))
    # to show that the main thread continues to execute
    # while the pool threads work on the tasks
    print("{}: tasks submitted".format(threading.current_thread().name))

if __name__ == '__main__':
    main()

输出:

Executing our Task = 1 and A
Executing our Task = 2 and B
MainThread: tasks submitted
Task Executed <Thread(ThreadPoolExecutor-0_0, started daemon 12192)>
Task Executed <Thread(ThreadPoolExecutor-0_1, started daemon 11800)>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2020-07-22
    相关资源
    最近更新 更多