возврат ThreadPoolExecutor в массив задач - PullRequest
0 голосов
/ 13 сентября 2018

Ниже приведен пример кода, который я получил от 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

1 Ответ

0 голосов
/ 14 сентября 2018

Я не смог воспроизвести ваш TypeError;по-видимому, у вас есть еще один код, который вы не показали нам.Как указал rockportrocker в их комментарии , вы не можете присвоить значения индексу, который еще не существует, поскольку вы пытаетесь присвоить будущее, возвращаемое из executor.submit(), для индекса 0 пустого списка typearr.Это поднимет упомянутое значение IndexError.

. Однако я мог бы выдать немного TypeError, и это из-за того, что вы неправильно набрали submit.

Документация Executor определяет параметр 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)>
...