并发.futures.ThreadPoolExecutor不打印错误

Ale*_*ana 6 python multithreading python-3.x concurrent.futures

我正在尝试使用并发.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)
Run Code Online (Sandbox Code Playgroud)

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

 def testMethodToExecInParallel(self, secondsToSleepFor):
Run Code Online (Sandbox Code Playgroud)

然后仍然将函数提交为:

future = executor.submit(testClass.testMethodToExecInParallel)
Run Code Online (Sandbox Code Playgroud)

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

def testMethodToExecInParallel(self):

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

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

理解这使得程序几乎无法调试是很简单的......有人可以解释我为什么会发生这种行为吗?

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

也许在提交给 ThreadPoolExecutor 类方法而不是简单的独立函数时存在某种问题,因此,这种行为是可以预料的吗?

或者也许错误是在线程内部抛出的,并且由于某种原因我无法读取它?

- 编辑 -

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

我认为必须警告用户有关 ThreadPoolExecutor 这种非常奇怪的行为:如果您只向 ThreadPoolExecutor 提交函数而不调用 future.result()

  • 如果代码正确,程序将继续运行并按预期运行
  • 如果代码中出现错误,程序似乎不会调用提交的函数,无论它做什么:它不会报告代码中的错误

小智 6

据我所知,“还没有”,您必须在“executor.submit(testClass.testMethodToExecInParallel)”之后调用“e.results()”才能执行 threadpool 。我已经尝试过你所说的,它给了我错误,下面是代码

>>> 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
Run Code Online (Sandbox Code Playgroud)

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