Python奇怪的文件读取行为,用于长时间运行的非块线程读取

时间:2011-07-13 20:55:06

标签: python multithreading file readline

我正在使用线程从标准输出编写非块读取文件的代码。我使用在线示例开始。启动子进程时会创建该文件。但是,在ResultEvent中读取文件后,文件将被清除。我无法调试线程,也不确定那里发生了什么。有谁给我一个线索?这是代码:

EVT_RESULT_ID = wx.NewId()
def EVT_RESULT(win, func):
    win.Connect(-1, -1, EVT_RESULT_ID, func)

class ResultEvent(wx.PyEvent):
    def __init__(self, data,file):
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        TOTAL = 0
        f = open(file, "r")
        while f:
            line = f.readline()
            s = line.split()
            n = len(s)
            if n == 0:
                break
            try:
                TOTAL += float( s[ n-1 ] )
            except:
                pass
        print TOTAL,line,file

        uu = f.read()
        print "self str start"
        print uu,file,data
        f.close()

class WorkerThread(Thread):
    def __init__(self, notify_window, exe,file):
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self._notify_window = notify_window
        self.exe = exe
        self.file = file
        self.start()

    def run(self):
        f = open(self.file, 'w')
        p = subprocess.Popen(exe, shell=False, stdout=subprocess.PIPE)
        f.close()
        self.str = p.stdout.readline()
        print "create file"
        print self.str,self.file

        wx.PostEvent(self._notify_window, ResultEvent(self.str,self.file))

结果是“创建文件”正确后打印。有一些写入文件的东西。 ResultEvent中的打印错误。我得到TOTAL为0,我也检查了它是空的文件。

2 个答案:

答案 0 :(得分:1)

您的代码有几个问题:

1)您正在调用Popen但不等待它完成 - 其余代码可能在管道创建完成之前执行。接下来你要做的就是关闭你用于stdout的文件,这就是为什么它总是空的。在关闭f之前,请致电p.wait()等待该过程完成。

2)while f:将永远循环(或直到你突破循环或抛出和异常)。与大多数对象一样,文件始终被视为True。这可能不是你的意思。

3)readline()调用是不必要的,因为文件对象是可迭代的。它更加pythonic(和更安全):

for line in f:
    do stuff with line

4)代码从文件中读取行,直到你遇到一个空行(即len(line.split())== 0)。如果您的文件中间某处有一个空行,则只能获得部分文件的总数。

5)在您遍历文件后调用f.read()。这只会从文件中的当前位置读取结束,因此如果您已经读取了文件中的所有行,则不会读取任何内容。如果您想在此时读取整个文件,请回头查看或关闭并重新打开文件。

6)s[n-1]是不必要的。使用s[-1]获取列表中的最后一个元素。

答案 1 :(得分:0)

要将命令作为子进程执行,如果命令执行失败,还应使用此语法检查:

pipe = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
stdout, stderr = pipe.communicate()
exitcode = pipe.returncode

此外,您不需要在执行命令之前和命令执行之后打开文件(这意味着什么?)。