【问题标题】:Reading a file, only if no other 'process' is working on it仅当没有其他“进程”在处理文件时才读取文件
【发布时间】:2018-03-19 20:52:03
【问题描述】:

我想打开 3 个 Powershell 并在其中 3 个上运行相同的代码,只是文件不同。
由于它们具有完全相同的逻辑,因此它们每个人都会尝试访问彼此的文件以检查那里是否写有任何内容
Process1 有client1.txt,Process2 有client2.txt,Process3 有client3.txt
下面是一些关于在选择要处理的问题之前进程 3 应该检查的代码:

import os
while True:
f = 'C:\Users\Files'
i = {}
i['word'] = 'problem X' #just an example, I'll have a whole list
if os.path.exists(f):
    try:
        os.rename(f, f)
        print 'Access on file "' + f +'" is available!'
        file1 = open('C:\Users\Files\client1.txt', 'r+')
        file2 = open('C:\Users\Files\client2.txt', 'r+')
        if file1.read() == i['word']:
            print "A process is already working on this problem, check another"
        elif file2.read() == i['word']:
            print "A process is already working on this problem, check another"
        else:
            print "Found a new problem to work on"
            file3 = open('C:\Users\Files\client3.txt', 'r+')
            file3.write(i['word'])
            file1.close()
            file2.close()
            file3.close()

    except OSError as e:
        print 'Access-error on file "' + f + '"! \n' + str(e)
        time.sleep(5)
        pass

我试图通过代码表示的是:我只希望一个进程在其他人尚未解决问题的情况下启动一个问题,因为他们都有相同的逻辑,他们会尝试解决相同的问题(我有很多需要解决的问题),因此它们可能会在程序继续使用while True 的同时到达。
当它完成问题时,它会删除文件的内容并选择一个新问题,然后将它正在处理的问题写入自己的文件中以供其他人稍后检查。

说清楚一点:假设 process1 发现问题首先工作('AAA'),它们都有空的 txt 文件,它会检查 txt2 和 txt3 并查看它不等于('AAA' ),然后它会将其写入自己的文件并关闭它。
我想要 process2 可能会在一秒钟后在那里读取 txt1 和 txt3 并看到 ('AAA') 已经在处理中,它将获得列表中的下一个并再次检查,看到 ('BBB' ) 没问题,它会写入自己的文件。
当它结束时,它会从 txt 中删除字符串并开始寻找另一个。

也存在两个进程同时尝试检查文件的问题。如果另一个进程正在使用该文件,是否有办法将time.sleep() 放入某个进程,然后稍后再试?

【问题讨论】:

  • 不是重复的,但可能相关:stackoverflow.com/questions/30407352/…
  • @paisanco 我只了解一般概念,因为我是 python 新手,但它真的很有趣。你认为他们提到的块会阻止我想要的那种进程,还是只是线程/多进程和具有“链接”的东西?

标签: python python-2.7 file


【解决方案1】:

理想情况下,您会使用 Python 的 multiprocessing 模块来启动每个进程。您可以让一个进程监视新文件并将它们提供给您的工作进程从中读取的queue。此解决方案将消除对任何文件锁定的需要,因为只有一个进程正在寻找新文件。

如果您必须通过 Power Shell 启动进程,则必须使用某种锁定来使进程协同工作。真正的文件锁定很难以跨平台的方式进行。不过,您可以使用 move 来伪造它。例如,您可以尝试移动文件(假设您要移动到同一文件系统上的某个位置,移动在大多数操作系统上是原子操作)。如果移动失败,您知道肯定是另一个进程先到达了它,或者操作系统出现了严重错误。然后,您可以对移动的文件进行所有处理。例如:

import path
import shutil

filename = "C:\\path\\to\\filename.txt"
_filename = os.path.join(os.path.basename(filename), ".wip")
wip_filename = os.path.join(os.path.dirname(filename), _filename)

try:
    shutil.move(filename, wip_filename)
except OSError:
    # another process moved it first
    pass
else:
    do_work(wip_filename) 

【讨论】:

  • 你其实给我解释了一些我自己的代码,我之前不明白。我想这无济于事,我将不再害怕多处理和排队。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 2017-03-08
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
相关资源
最近更新 更多