我有客户端和服务器模块,每个模块都可以通过一个函数启动。我只需要找到一种平行运行摊位的方法:
如果客户端/服务器发生异常会阻止另一个,那么测试运行器就不会卡住
如果客户端/服务器中发生异常,则会打印异常或将其传播给运行器,以便我可以看到它并使用测试套件调试客户端/服务器
最好使用线程
在线程的run方法中捕获异常时,使用简单线程的第一个暂定用以os._exit(1)
结尾(这会杀死测试运行符...)编辑:使用线程包
第二个尝试(试图避免使用os._exit())是concurrent.futures.ThreadPoolExecutor
。它允许从线程中获取异常但我仍然找不到中止其他线程的方法。
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
server_future = executor.submit(server)
client_future = executor.submit(client)
concurrent.futures.wait([server_future, client_future],
return_when=concurrent.futures.FIRST_EXCEPTION)
if client_future.done() && client_future.exception():
# we can handle the client exception here
# but how to stop the server from waiting the client?
# also, raise is blocking
if server_future.done() && server_future.exception():
# same here
编辑:客户端或服务器将在accept()或receive()调用上被阻止,因此我无法定期汇集一个标志决定退出。(停止线程的经典方法之一)
答案 0 :(得分:1)
您可以使用threading包。请注意,虽然强制杀死线程不是一个好主意,as discussed here。似乎没有官方方法可以在Python中杀死Thread,但是您可以按照链接帖子上给出的示例之一进行操作。
现在你需要等待一个线程退出才停止另一个线程,避免你的测试运行器被卡住。您可以使用包装服务器/客户端启动的线程,让主线程等待客户端/服务器线程退出,然后再杀死另一个。
您可以像这样定义客户端/服务器线程:
# Server thread (replace
class testServerThread (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# Do stuff if required
def run(self):
try:
startServer() # Or startClient() for your client thread
except: Exception
# Print your exception here, so you can debug
然后,启动客户端和服务器线程,并等待其中一个退出。一旦其中一个不再活着,你可以杀死另一个并继续测试。
# Create and start client/server
serverThread = testServerThread ()
clientThread = testClientThread ()
serverThread.start()
clientThread.start()
# Wait at most 5 seconds for them to exit, and loop if they're still both alive
while(serverThread.is_alive() and clientThread.is_alive()):
serverThread.join(5)
clientThread.join(5)
# Either client or server exited. Kill the other one.
# Note: the kill function you'll have to define yourself, as said above
if(serverThread.is_alive()):
serverThread.kill()
if(clientThread.islive()):
clientThread.kill()
# Done! Your Test runner can continue its work
代码的核心是join()函数:
等到线程终止。这会阻塞调用线程,直到调用join()方法的线程终止 - 正常或通过未处理的异常 - 或者直到发生可选的超时。
因此,在我们的情况下,它将等待5秒钟的客户端和5秒钟的服务器,如果它们两个仍然活着,它将再次循环。每当其中一个退出时,循环就会停止,剩下的线程将被杀死。