【问题标题】:concurrent.futures.ThreadPoolExecutor doesn't print errorsconcurrent.futures.ThreadPoolExecutor 不打印错误
【发布时间】:2019-07-13 15:32:18
【问题描述】:

我正在尝试使用 concurrent.futures.ThreadPoolExecutor 模块来并行运行类方法,我的代码的简化版本几乎如下:

class TestClass:

    def __init__(self, secondsToSleepFor):

        self.secondsToSleepFor = secondsToSleepFor


    def testMethodToExecInParallel(self):

        print("ThreadName: " + threading.currentThread().getName())


        print(threading.currentThread().getName() + " is sleeping for " + str(self.secondsToSleepFor) + " seconds")


        time.sleep(self.secondsToSleepFor)


        print(threading.currentThread().getName() + " has finished!!")


with concurrent.futures.ThreadPoolExecutor(max_workers = 2) as executor:

    futuresList = []

    print("before try")

    try:

         testClass = TestClass(3)        

         future = executor.submit(testClass.testMethodToExecInParallel)

         futuresList.append(future)

    except Exception as exc:

         print('Exception generated: %s' % exc)

如果我执行此代码,它的行为似乎与预期的一样。 但是如果我犯了一个错误,比如在“testMethodToExecInParallel”中指定了错误数量的参数,比如:

 def testMethodToExecInParallel(self, secondsToSleepFor):

然后仍然提交函数为:

future = executor.submit(testClass.testMethodToExecInParallel)

或尝试在“testMethodToExecInParallel”方法的打印语句中将字符串对象与整数对象连接(不使用 str(.) ):

def testMethodToExecInParallel(self):

        print("ThreadName: " + threading.currentThread().getName())
        print("self.secondsToSleepFor: " + self.secondsToSleepFor) <-- Should report an Error here

程序不返回任何错误;只是打印“尝试前”并结束执行...

理解这使得程序几乎无法调试是微不足道的......有人可以解释一下为什么会发生这种行为吗?

(对于第一种错误)concurrent.futures.ThreadPoolExecutor 不检查具有指定签名的函数以提交,并最终抛出某种“noSuchFunction”异常?

也许在提交到 ThreadPoolExecutor 类方法而不是简单的独立函数时会出现某种问题,因此,这种行为是可以预期的?

或者错误是在线程内部抛出的,由于某种原因我无法阅读?

-- 编辑--

Akshay.N 建议在向 ThreadPoolExecutor 提交函数后插入 future.result() 使程序按预期运行:如果代码正确则运行良好,如果代码中有错误则打印错误。

必须警告用户注意 ThreadPoolExecutor 的这种非常奇怪的行为: 如果您只向 ThreadPoolExecutor 不调用 future.result() 提交函数: - 如果代码正确,则程序继续运行并按预期运行 - 如果代码中的某些错误似乎程序没有调用提交的函数,不管它做什么:它不会报告代码中的错误

【问题讨论】:

    标签: python python-3.x multithreading concurrent.futures


    【解决方案1】:

    据我所知,“到目前为止”,您必须在“executor.submit(testClass.testMethodToExecInParallel)”之后调用“e.results()”才能执行线程池。 我已经试过你说的,它给了我错误,下面是代码

    >>> import concurrent.futures as cf
    >>> executor = cf.ThreadPoolExecutor(1)
    >>> def a(x,y):
    ...     print(x+y)
    ...
    >>> future = executor.submit(a, 2, 35, 45)
    >>> future.result()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Users\username 
    \AppData\Local\Programs\Python\Python37\lib\concurrent\futures\_base.py", line 
    425, in result
        return self.__get_result()
      File "C:\Users\username
    \AppData\Local\Programs\Python\Python37\lib\concurrent\futures\_base.py", line 
    384, in __get_result
        raise self._exception
      File "C:\Users\username
    \AppData\Local\Programs\Python\Python37\lib\concurrent\futures\thread.py", line 
    57, in run
        result = self.fn(*self.args, **self.kwargs)
    TypeError: a() takes 2 positional arguments but 3 were given
    

    如果它仍然不起作用,请告诉我

    【讨论】:

    • 在那种情况下,我不明白为什么我的代码的第一个 sn-p 工作正常......如果需要调用 e.results() 来执行线程,我希望程序能够即使在这种情况下也只打印“尝试前”并退出......
    • 非常感谢!添加future.result()它似乎像预期的那样工作:如果代码正确则正常,如果有问题则打印错误......无论如何我认为向已经/将要的用户报告这种奇怪的行为很重要和我的情况一样
    • future = executor.submit(f, vars) 后跟 print(f'{future.result()}') 也对我有用。感谢你们俩的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多