使用2个不同的程序同步读取和写入同一文本文件中的问题

时间:2014-03-04 06:06:50

标签: python python-2.7 file-io pyglet

我有一个文本文件,它充当程序A的源和程序B的接收器。负责更新文件的程序B在定期的时间间隔内完成,并且总是覆盖文件。正在读取文件的程序A不断读取它并在发生这种情况时接收更新的值。一段时间它工作正常。但最终,程序A崩溃了。显示的错误是:

File "/home/../baba_rect.py", line 61, in on_draw
     if (int(a[core_id]) <= 100):
 ValueError: invalid literal for int() with base 10: '' 

以下是计划A的代码:

    import sys, time, math, os, random
    from pyglet.gl import *

    red = [255,0,0]
    green = [0,255,0]
    blue = [0,0,255]
    black = [0,0,0]

    dim_x = 2;
    dim_y = 2;

    window = pyglet.window.Window()

    label = pyglet.text.Label('Simulation', 
                              font_name='Times New Roman', 
                              font_size=16,
                              color=(204,204,0,255),      #red font (255,0,0) opacity=255
                              x=window.width, y=window.height,
                              anchor_x='right', anchor_y='top') 

    class FilledSquare:
        def __init__(self, width, height, xpos, ypos):
            self.xpos = xpos
            self.ypos = ypos
            self.angle = 0
            self.size = 1
            x = width/2.0
            y = height/2.0
            self.vlist = pyglet.graphics.vertex_list(4, ('v2f', [-x,-y, x,-y, -x,y, x,y]), ('t2f', [0,0, 1,0, 0,1, 1,1]))  
        def draw(self,w,h,x,y):
            self.width=w
            self.height=h
            self.xpos=x
            self.ypos=y
            glPushMatrix()
            glTranslatef(self.xpos, self.ypos, 0)
            self.vlist.draw(GL_TRIANGLE_STRIP)        
            glPopMatrix()


    @window.event
    def on_draw():
        window.clear()
        glClearColor(0, 0.3, 0.5, 0)
        glClear(GL_COLOR_BUFFER_BIT)
        label.draw()

        for i in range(0,dim_x):
            for j in range(0,dim_y):
                print i,",",j
                #read file
                f = open('r.txt', 'r')
                a = f.readline()
                a = a.rstrip('\n')
                a = a.split(" ")
                f.close()
                #core_id
                core_id = j*dim_x + i;
                if (int(a[core_id]) <= 100):
                    color = red
                elif (int(a[core_id]) <= 200):
                    color = green
                elif (int(a[core_id]) <= 300):
                    color = blue
                else:
                    color = black

                glColor3f(color[0], color[1],color[2])
                squares[i+j].draw(60,60,i*50+200,j*50+200)     

    squares = [FilledSquare(30, 30, 0, 0), FilledSquare(30, 30, 0, 0), FilledSquare(30, 30, 0, 0), FilledSquare(30, 30, 0, 0)]   # 2x2

    pyglet.app.run() 

这就是文本文件 r.txt 在任何时刻的样子:

  

10 20 120 235

我认为崩溃的原因是因为在那时,Pgm A和Pgm B同时访问文件而Pgm A读取“”而不是数字无法转换为int()。如果我的结论确实如此,那么我该如何克服这个问题呢?

或者:是否可以使pyglet.app.run()对 r.txt 的任何更改敏感?即Pgm A仅在文本文件发生变化时运行,从而避免冲突。

1 个答案:

答案 0 :(得分:0)

使用flockhttp://docs.python.org/2/library/fcntl.html#fcntl.flock

使用inotify:https://github.com/seb-m/pyinotify收听文件更改。但是,这不是正确锁定文件的解决方案。

更新:

f = open('filename', 'r')
fcntl.flock(f, fcntl.LOCK_EX) # Get exclusive lock
do_stuff(f)
fcntl.flock(f, fcntl.LOCK_UN)
f.close()