在 Python 中,线程的自修复通常涉及异常处理和适当的线程管理。在线程的 run()
方法中使用 try-except
块来捕获可能发生的异常。在捕获异常后,可以记录异常信息或者尝试重新启动线程以恢复正常运行。下面看看我最近的一个实操案例。
1、问题背景
我创建了一个访问米国和欧某盟服务器的网络蜘蛛。米国和欧某盟的服务器是相同的数据结构,但内部的数据不同,我想把它们全部整理出来。为了对服务器友好,每次请求之间都会有一个等待时间。由于程序完全相同,为了加快处理速度,我将程序进行了多线程处理,以便可以同时访问欧某盟和米国服务器。这个爬取过程大约需要几周,而不是几天。会出现异常,虽然我试图在程序内部处理所有内容,但很可能会出现一些奇怪的问题。为了真正防御这个问题,我想捕获一个出现故障的线程,记录错误并重新启动它。最坏的情况是,我从数千页中丢失了几页,这比线程出现故障而损失 50% 的速度要好。然而,根据我的阅读,Python 线程会静默地死去。有没有人有什么想法?
class AccessServer(threading.Thread):
def __init__(self, site):
threading.Thread.__init__(self)
self.site = site
self.qm = QueueManager.QueueManager(site)
def run(self):
# Do stuff here
def main():
us_thread = AccessServer(u"us")
us_thread.start()
eu_thread = AccessServer(u"eu")
eu_thread.start()
2、解决方案
方法一:
在 run
方法中使用一个 try: ... except: ...
块。如果发生某种奇怪的事情导致线程失败,很可能会在代码的某个地方抛出一个错误(而不是在多线程子系统本身中);这样你就可以捕获它,对其进行记录,并重新启动线程。是否要实际关闭线程并启动一个新线程,或者只是将 try/except
块包含在一个 while
循环中,以便同一个线程继续运行,由你决定。
方法二:
如果怀疑可能会发生一些非常奇怪的事情,而你无法通过 Python 的错误处理机制来检测到,另一个解决方案是启动一个监视线程,定期检查其他线程是否正常运行。
代码示例:
import threading
import Queue
class AccessServer(threading.Thread):
def __init__(self, site):
threading.Thread.__init__(self)
self.site = site
self.qm = QueueManager.QueueManager(site)
def run(self):
try:
# Do stuff here
except Exception as e:
# Log the error
print(f"Error: {e}")
# Restart the thread
self.run()
def main():
us_thread = AccessServer(u"us")
us_thread.start()
eu_thread = AccessServer(u"eu")
eu_thread.start()
或者:
import threading
import time
class AccessServer(threading.Thread):
def __init__(self, site):
threading.Thread.__init__(self)
self.site = site
self.qm = QueueManager.QueueManager(site)
def run(self):
while True:
try:
# Do stuff here
except Exception as e:
# Log the error
print(f"Error: {e}")
# Restart the thread
self.run()
def main():
us_thread = AccessServer(u"us")
us_thread.start()
eu_thread = AccessServer(u"eu")
eu_thread.start()
def monitor_threads():
while True:
# Check if the threads are still running
if not us_thread.is_alive() or not eu_thread.is_alive():
# Restart the threads
us_thread = AccessServer(u"us")
us_thread.start()
eu_thread = AccessServer(u"eu")
eu_thread.start()
# Sleep for a bit
time.sleep(1)
# Start the monitor thread
monitor_thread = threading.Thread(target=monitor_threads)
monitor_thread.start()
通过上面的这些方法,最终我们可以在 Python 中实现一定程度的线程自修复功能,确保线程在遇到异常时能够进行适当的处理,从而提高程序的稳定性和可靠性。