Как обнаружить исключения в concurrent.futures в Python3?

Я только что перешел на python3 из-за его параллельного модуля фьючерсов. Мне было интересно, смогу ли я заставить его обнаруживать ошибки. Я хочу использовать параллельные фьючерсы для параллельной программы, если есть более эффективные модули, сообщите мне.

Мне не нравится многопроцессорность, так как она слишком сложна, а документации не так много. Однако было бы здорово, если бы кто-то мог написать Hello World без классов, только функции, использующие многопроцессорность для параллельных вычислений, чтобы это было легко понять.

Вот простой скрипт:

from concurrent.futures import ThreadPoolExecutor

def pri():
    print("Hello World!!!")

def start():
    try:
        while True:
            pri()
    except KeyBoardInterrupt:
        print("YOU PRESSED CTRL+C")


with ThreadPoolExecutor(max_workers=3) as exe:
    exe.submit(start)

Приведенный выше код был просто демонстрацией того, как CTRL+C не будет работать для печати инструкции.

Я хочу иметь возможность вызывать функцию, если присутствует ошибка. Это обнаружение ошибок должно исходить от самой функции.

Другой пример

import socket
from concurrent.futures import ThreadPoolExecutor 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
def con():
    try:
        s.connect((x,y))
        main()
    except: socket.gaierror
         err()
def err():
    time.sleep(1)
    con()
def main():
    s.send("[+] Hello")
with ThreadPoolExecutor as exe:
    exe.submit(con)

person Community    schedule 31.10.2015    source источник
comment
Итак, вы хотите поймать KeyBoardInterrupt? Это то, о чем вы спрашиваете?   -  person laike9m    schedule 01.11.2015
comment
Так в чем твой вопрос?   -  person laike9m    schedule 01.11.2015
comment
Вы хотите иметь возможность печатать ВЫ НАЖАЛИ CTRL+C?   -  person laike9m    schedule 01.11.2015
comment
Давайте продолжим обсуждение в чате.   -  person    schedule 01.11.2015
comment
связанные: stackoverflow.com/questions/35711160/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 20.03.2019


Ответы (2)


Вот решение. Я не уверен, что тебе это нравится, но я не могу придумать ничего другого. Я изменил ваш код, чтобы он работал.

from concurrent.futures import ThreadPoolExecutor
import time

quit = False

def pri():
    print("Hello World!!!")

def start():
    while quit is not True:
        time.sleep(1)
        pri()

try:
    pool = ThreadPoolExecutor(max_workers=3)
    pool.submit(start)

    while quit is not True:
        print("hei")
        time.sleep(1)
except KeyboardInterrupt:
    quit = True

Вот пункты:

  1. #P3#
    #P4# #P5#
    #P6#
    pool = ThreadPoolExecutor(max_workers=3)
    pool.submit(start)
    
  2. Основной поток должен выполнять «работу», чтобы иметь возможность перехватывать Ctrl+C. Таким образом, вы не можете просто оставить основной поток и выйти, самый простой способ - запустить бесконечный цикл

  3. Теперь, когда у вас есть цикл, работающий в основном потоке, когда вы нажмете CTRL+C, программа войдет в блок except KeyboardInterrupt и установит quit=True. Затем ваш рабочий поток может выйти.

Строго говоря, это всего лишь обходной путь. Мне кажется, что другого пути для этого быть не может.

Изменить
Я не уверен, что вас беспокоит, но вы можете без проблем поймать исключение в другом потоке:

import socket
import time
from concurrent.futures import ThreadPoolExecutor 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

def con():
    try:
        raise socket.gaierror
        main()
    except socket.gaierror:
        print("gaierror occurred")
        err()

def err():
    print("err invoked")
    time.sleep(1)
    con()

def main():
    s.send("[+] Hello")

with ThreadPoolExecutor(3) as exe:
    exe.submit(con)

Выход

gaierror occurred
err invoked
gaierror occurred
err invoked
gaierror occurred
err invoked
gaierror occurred
...
person laike9m    schedule 01.11.2015
comment
Нет, к сожалению, это не то, что мне нужно. Мне нужно поймать исключения из самой функции. Но это заслуживает плюса. Может ли python2.7 решить мою проблему? - person ; 01.11.2015
comment
ловить исключения != ловить ctrl+c. Если вы хотите поймать прерывание клавиатуры, боюсь, это единственный способ. - person laike9m; 01.11.2015
comment
@IsithaSubasinghe Тогда просто поймай это. - person laike9m; 01.11.2015
comment
Я хочу поймать его, чтобы он мог повторить попытку, поэтому con() try: s.connect((x,y)) с исключением: main() . def main(): ошибка печати, time.sleep(1), con()..............Извините за неправильное форматирование, я задам новый вопрос, если вы хотите, чтобы я - person ; 01.11.2015
comment
Вот и сделал лучше - person ; 01.11.2015
comment
У меня не работает, на самом деле он не подключается и не попадает в main() - person ; 04.11.2015
comment
@IsithaSubasinghe Какой результат вы увидели? Какую версию Python вы используете? На какой платформе? - person laike9m; 04.11.2015
comment
@IsithaSubasinghe Понятно. Я не писал код, который вы действительно можете использовать, просто чтобы доказать свою точку зрения. Я вызываю исключение перед main, конечно, вы не можете добраться до main. - person laike9m; 04.11.2015
comment
да, я знаю, что снял повышение и попытался подключиться к открытому порту на своем ноутбуке, но на самом деле это не сработало. - person ; 04.11.2015
comment
Он просто пропускает соединение ((x, y)) с тем же выходом. - person ; 04.11.2015
comment
@IsithaSubasinghe Если вы действительно хотите, чтобы ваш код работал, вам действительно следует задать еще один вопрос. Я думаю, что этот вопрос касается только того, как обнаружить исключение. Если вы попытаетесь решить здесь несколько задач, это запутает будущих читателей. - person laike9m; 04.11.2015
comment
Вот моя реальная проблема stackoverflow.com/questions/33513017/ Я опубликовал вышеизложенное, чтобы другие люди могли извлечь из этого пользу, поскольку параллелизм python - это боль - person ; 04.11.2015
comment
Я очень извиняюсь за сообщение выше, спасибо за помощь, я сделал простую глупую ошибку, еще раз извиняюсь за весь этот вопрос. - person ; 04.11.2015
comment
@IsithaSubasinghe Нет глупого вопроса, тебе действительно не нужно извиняться. - person laike9m; 04.11.2015

Слишком поздно на вечеринку, но, может быть, это поможет кому-то еще...

Я почти уверен, что на исходный вопрос на самом деле не было ответа. Люди зациклились на том факте, что пользователь 5327424 использовал прерывание клавиатуры для возбуждения исключения, когда дело было в том, что исключение (как бы оно ни было вызвано) не было возбуждено. Например:

import concurrent.futures


def main():
    numbers = range(10)

    with concurrent.futures.ThreadPoolExecutor() as executor:
        results = {executor.submit(raise_my_exception, number): number for number in numbers}


def raise_my_exception(number):
    print('Proof that this function is getting called. %s' % number)
    raise Exception('This never sees the light of day...')


main()

Когда приведенный выше пример кода будет выполнен, вы увидите текст внутри оператора печати, отображаемый на экране, но вы никогда не увидите исключение. Это связано с тем, что результаты каждого потока хранятся в объекте results. Вам нужно повторить этот объект, чтобы добраться до ваших исключений. В следующем примере показано, как получить доступ к результатам.

import concurrent.futures


def main():
    numbers = range(10)

    with concurrent.futures.ThreadPoolExecutor() as executor:
        results = {executor.submit(raise_my_exception, number): number for number in numbers}

    for result in results:
        # This will cause the exception to be raised (but only the first one)
        print(result.result())


def raise_my_exception(number):
    print('Proof that this function is getting called. %s' % number)
    raise Exception('This will be raised once the results are iterated.')


main()

Я не уверен, нравится мне такое поведение или нет, но оно позволяет полностью выполнять потоки, независимо от исключений, возникающих внутри отдельных потоков.

person Hans Goldman    schedule 27.11.2019