Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python3的concurrent.futures中检测异常?_Python_Python 2.7_Multiprocessing_Python 3.4_Concurrent.futures - Fatal编程技术网

如何在Python3的concurrent.futures中检测异常?

如何在Python3的concurrent.futures中检测异常?,python,python-2.7,multiprocessing,python-3.4,concurrent.futures,Python,Python 2.7,Multiprocessing,Python 3.4,Concurrent.futures,由于python3的并发未来模块,我刚刚转到python3。我想知道我是否可以让它检测错误。我想使用并发期货并行程序,如果有更有效的模块,请让我知道 我不喜欢多重处理,因为它太复杂,没有太多的文档。但是,如果有人能够编写一个Hello World,而不使用类和函数,使用多处理来并行计算,这样就很容易理解了,那就太好了 下面是一个简单的脚本: from concurrent.futures import ThreadPoolExecutor def pri(): print("Hello

由于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)
这是一个解决办法。我不确定你是否喜欢,但我想不出其他的。我已经修改了你的代码使它工作

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
以下是要点:

  • 当您将
    与ThreadPoolExecutor(max_workers=3)一起作为exe使用时,它将等待所有任务完成。看看

    如果
    wait
    为True,则此方法将不会返回,直到执行完所有挂起的期货并且释放了与执行器关联的资源。如果wait为
    False
    ,则此方法将立即返回,并且在执行完所有挂起的期货后,将释放与执行器关联的资源。不管wait的值是多少,整个Python程序都不会退出,直到所有挂起的未来都执行完毕

    如果使用
    with
    语句,则可以避免显式调用此方法,该语句将关闭
    执行器
    (等待时就好像
    Executor.shutdown()

    这就像在线程上调用
    join()

    这就是为什么我将其替换为:

    pool = ThreadPoolExecutor(max_workers=3)
    pool.submit(start)
    
  • 主线程必须执行“工作”才能捕获Ctrl+C。因此,您不能将主线程留在那里然后退出,最简单的方法是运行无限循环

  • 现在在主线程中运行了一个循环,当您点击
    CTRL+C
    时,程序将进入
    除键盘中断之外的
    块,并设置
    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
    ...
    

    去派对已经太晚了,但也许会对其他人有所帮助

    我很确定最初的问题没有得到真正的回答。用户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()
    

    我不确定我是否喜欢这种行为,但它确实允许线程完全执行,而不管在各个线程中遇到的异常。

    那么您想捕获
    键盘中断
    ?这就是你要问的吗?那你的问题是什么?你想打印“你按下了CTRL+C”?让我们看看。相关:不,不幸的是,这不是我需要的。我需要从函数本身捕获异常。但这值得投票表决。python2.7能解决我的问题吗?“捕获异常”!=“catch ctrl+c”。如果你想捕捉键盘中断,恐怕这是唯一的方法。@IsithaSubasinghe然后就捕捉它。我想捕捉它以便它可以重试,所以con()try:s.connect((x,y))使用except:main()。def main():打印“error”,time.sleep(1),con()………很抱歉格式不正确,如果你想问我,我会问一个新问题。你去哪里会更好