多个python子线程中的某个异常退出,如何让主线程继续它的工作,或者记录下被耽搁的工作?
天蓬老师
天蓬老师 2017-04-18 09:19:17
[Python讨论组]

如下是一个爬虫的部分代码,现在碰到的问题是,多个线程(比如10个)中的某个在爬取、解析某个页面或者存储数据的过程中发生了异常,子线程的工作代码虽然捕捉了这一异常,但无法继续工作。

我希望最好有办法能不让线程退出,而继续分配给他的工作;退而求其次,可以开启一个新的线程继续他的工作,但这需要发生异常的线程将退出节点的信息返回给主线程;最次的,异常退出的线程应该将退出节点的信息返回并让主线程记录,方便我后面单独处理。

我不知道最佳诉求是否可以实现,或者如果不能实现,怎样可以将发生异常的线程的关键信息返回,我看了python 主线程捕获子线程异常这篇文章,大约知道思路,但他的示例中只开启了一个单独的线程,而我开始了多个线程,有一些特殊性,然后就不知道怎么处理了。

请问最优方案是否有解,以及如何获取多个子线程中某个发生异常的子线程的返回信息呢?

def getAllItems(startNum, endNum, tcount = 10):
    threads = []
    for torder in range(tcount):
        t = MyThread(torder, tcount, startNum, endNum)
        t.start()
        threads.append(t)
    for t in threads:
        t.join()
    dbUtils.closeCur()
    dbUtils.closeConn()
    print "INFO: cursor and connection closed, work done!"

class MyThread(threading.Thread):
    def __init__(self, torder, tcount, startNum, endNum):
        threading.Thread.__init__(self)
        self.torder = torder
        self.tcount = tcount
        self.startNum = startNum
        self.endNum = endNum
    
    def run(self):
        try:
            for i in range(self.startNum+self.torder, self.endNum+1, self.tcount):
                item = downloadItem(i, htmlDownloader, logFile)
                if item:
                    if databaseMutex.acquire():
                        try:
                            dbUtils.cur.execute(sql, item)
                            print "INFO: item #" + str(i) + " saved"
                            databaseMutex.release()
                        except Exception,e:
                            databaseMutex.release() # prevent work blocked
                            # raise e
        except Exception,e:
            excepinfo = "Error: can not save item #" + str(i) + " to database, " + str(e)
            print excepinfo
            if logFileMutex.acquire():
                with codecs.open(logFile, 'a', 'utf-8') as f:
                    f.write(excepinfo + "\n")
                logFileMutex.release()
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(1)
巴扎黑

一个线程和多个线程其实道理一样,代码可以改成如下:
def getAllItems(startNum, endNum, tcount = 10):

threads = []
for torder in range(tcount):
    t = MyThread(torder, tcount, startNum, endNum)
    threads.append(t)
**try:
    for t in threads:
        t.start()
        t.join()
except Exception, e:
    print t. exc_traceback**
dbUtils.closeCur()
dbUtils.closeConn()
print "INFO: cursor and connection closed, work done!"
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号