【问题标题】:Automatic Stack Trace not being given in threads other than the main thread主线程以外的线程中未给出自动堆栈跟踪
【发布时间】:2015-04-22 22:15:20
【问题描述】:

我有一个相当大的程序,它从一个 excel 文件加载一些数据并填充一个表单,由于文件的大小,这可能需要很长时间,所以我一直将加载函数移到一个单独的线程上,唯一的问题是由于某种原因,在这个新线程中,每当发生错误时,我都没有在控制台中获得自动堆栈跟踪。它只是默默地失败了,这使得调试它真的很痛苦。

我在 Eclipse 中使用 pydev,我编写了以下测试用例以确保一切正常。

    from PyQt4 import QtCore

class OtherThread(QtCore.QThread):


    def __init__(self):
        super(OtherThread, self).__init__()

    def run(self):
        try:
            print(1/0)
        except Exception as e:
            print("exception caught in other thread: \n{0}".format(e))

class MainThread():

    def __init__(self):
        self.otherThread = OtherThread()

    def run(self):
        try:
            print(1/0)
        except Exception as e:
            print("exception caught in main thread: \n{0}".format(e))

        self.otherThread.run()

def main():
    mainThread = MainThread()

    mainThread.run()

if __name__ == '__main__':
    main()

当我运行它时,两个异常都被正确捕获,当我注释掉tread对象中的try块时,它也可以正常工作,我得到了我的堆栈跟踪。我真的不知道发生了什么。我可以做些什么来导致这种行为吗?

这是我正在开发的程序的代码。

    def run(self):
        print("excel thread running")

        workbook = xlrd.open_workbook(self.path)
        worksheet = workbook.sheet_by_name('PNA Form')
# 
        currentRow = 13 # start grabbing pna data
        numRowStart = currentRow
        newPartCol= 0
        oldPartCol = 10
        descriptionCol = 2
# 
        numberOfRows = worksheet.nrows - 1
#     
        print("number of rows = {0}".format(numberOfRows))
        PNA = []
#         
        current_color = False
        while (currentRow < numberOfRows):

            print("about to parse excel rows")
            newPartCell = int(worksheet.cell(currentRow,newPartCol).value)
            oldPartCell = int(worksheet.cell(currentRow,oldPartCol).value)
            descriptionCell =  QtCore.QString(worksheet.cell(currentRow,descriptionCol).value)

            print("excel rows parsed: {0}, {1}, {2}, {3}".format(oldPartCell,newPartCell,descriptionCell,current_color))

            print("running line excel row {0}: {1}".format(currentRow, str(descriptionCell)))
            if not self.isStrikethrough(currentRow,0): #make sure the line does not have strike through
                #self.guiHandel.BOMVal.addPNARow(oldPN = oldPartCell, newPN = newPartCell, disc = descriptionCell)
                print("about to emit pna row tracker for {0}".format(descriptionCell))
                self.addPNARowTracker.emit(oldPartCell,newPartCell,descriptionCell)
                print("thread still running after pna row tracker emit")

            if (oldPartCell != "" and not self.isStrikethrough(currentRow,0)):
                PNA.append((num(oldPartCell),num(newPartCell)))
                current_color = not current_color
                #self.guiHandel.pnaVerticalLayoutScroll.addWidget(PNACell(oldPartCell,newPartCell,descriptionCell,color = current_color))
                print("about to emit addPNARow: {0}, {1}, {2}, {3}".format(oldPartCell,newPartCell,descriptionCell,current_color))
                self.addPNARow.emit(oldPartCell,newPartCell,descriptionCell,current_color)
                #self.guiHandel.widgetStack.append(PNACell(oldPartCell,newPartCell,descriptionCell,color = current_color))
                print("thread still running after add pna row emit")

            currentRow += 1

            #self.guiHandel.pbar.setValue(int(100*(currentRow-13)/numberOfRows))
            print("currentRow =",currentRow)
            self.updateProgress.emit(int(100*(currentRow-numRowStart)/(numberOfRows-numRowStart)))

        print(PNA)
        self.done.emit()

这是失败时的控制台输出。

slot add pna row tracker called
running is about to return
about to emit addPNARow: 28458820, 28489881, INST CSTR-ASM,DIESEL,KM,UP,GAT, False
thread still running after add pna row emit
('currentRow =', 29slot add pna row called)

about to parse excel rows
Added addPNARow: 28458820, 28489881, INST CSTR-ASM,DIESEL,KM,UP,GAT, False
excel progress update called ------- progress = 20

当通过调试器运行时,它会停在这一行:

newPartCell = int(worksheet.cell(currentRow,newPartCol).value)

我尝试将它包装在一个 try 块中,但它从未遇到异常。它试图读取的单元格是空白的。

这里发生了什么?任何想法将不胜感激。

【问题讨论】:

  • 我刚刚确认空行是导致它挂起的原因。我为第 5 行输入制作了一个空白行的测试用例,但它失败了。但是我不明白为什么,这与我在一个线程上完成所有这些操作时使用的代码几乎完全相同。
  • 删除了 int() 和 QString 函数,现在代码正确执行直到结束,例如:newPartCell = int(worksheet.cell(currentRow,newPartCol).value)newPartCell = worksheet.cell(currentRow,newPartCol).value 我仍然想知道为什么这个线程上的错误没有被捕获虽然正确。
  • 在我之前的评论中说它正在正常执行,但事实并非如此,似乎信号正在将数字数据传输为乱码,一切都是预期的两倍。

标签: python multithreading pydev xlrd


【解决方案1】:

在此处找到问题的答案:error in pyqt qthread not printed

基本上你需要手动封装QThread对象的整个run方法,然后手动rethrow errors到stderr

【讨论】:

    猜你喜欢
    • 2012-06-28
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多