在POSIX系统上,rename(2)提供原子重命名操作,包括覆盖目标文件(如果存在)以及权限是否允许.
有没有办法在Windows上获得相同的语义?我知道Vista和Server 2008上的MoveFileTransacted(),但我需要它来支持Win2k及更高版本.
这里的关键词是原子 ......解决方案不能以任何方式使操作失败,使操作处于不一致状态.
我见过很多人说在win32上这是不可能的,但我问你,是不是真的?
如果可能,请提供可靠的引用.
想象一下,您有一个用于处理某种XML文件或配置文件的库.该库将整个文件读入内存并提供编辑内容的方法.完成操作内容后,可以调用a write将内容保存回文件.问题是如何以安全的方式做到这一点.
覆盖现有文件(开始写入原始文件)显然不安全.如果write方法在完成之前失败,则最终会得到一个半写文件并且您丢失了数据.
更好的选择是在某处写入临时文件,当write方法完成后,将临时文件复制到原始文件.
现在,如果副本以某种方式失败,您仍然可以在临时文件中正确保存数据.如果复制成功,您可以删除临时文件.
在POSIX系统上,我猜你可以使用rename系统调用,这是一个原子操作.但是你如何在Windows系统上做到最好?特别是,你如何使用Python处理这个问题?
另外,还有另一种安全写入文件的方案吗?
我有两个线程,一个写入文件,另一个周期性地将文件移动到另一个位置.写入总是open在写入消息之前调用,并close在写入消息之后调用.搬家公司使用shutil.move来搬家.
我看到第一次移动完成后,编写器无法再写入文件,即第一次移动后文件的大小始终为0.难道我做错了什么?
我有一个昂贵的函数,它接收并返回少量数据(一些整数和浮点数).我已经记住了这个功能,但我想让备忘录持久化.已经有几个与此相关的线程,但我不确定某些建议方法的潜在问题,我有一些相当具体的要求:
multiprocessing和来自不同的python脚本)该主题讨论了该shelve模块,该模块显然不是过程安全的.其中两个答案建议使用fcntl.flock锁定搁置文件.然而,这个帖子中的一些回答似乎表明这充满了问题 - 但我不确定它们是什么.这听起来好像只限于Unix(虽然显然Windows有一个等效的称为msvcrt.locking),而锁只是'建议' - 即它不会阻止我在不检查它被锁定的情况下意外写入文件.还有其他潜在的问题吗?写入文件的副本,并将主副本替换为最后一步,是否会降低腐败风险?
看起来dbm模块看起来不比搁置更好.我已经快速浏览了sqlite3,但为此目的看起来有点过分. 这个帖子和这个提到了几个第三方库,包括ZODB,但是有很多选择,而且它们对于这个任务来说都显得过于庞大和复杂.
有人有建议吗?
更新:有点提到下面的IncPy,看起来非常有趣.不幸的是,我不想回到Python 2.6(我实际上使用3.2),看起来使用C库有点尴尬(我大量使用numpy和scipy等).
kindall的另一个想法是有启发性的,但我认为将其调整为多个进程会有点困难 - 我想用文件锁定或数据库替换队列是最容易的.
再次看ZODB,它确实看起来非常适合这项任务,但我确实希望避免使用任何其他库.我还不完全确定简单使用的所有问题是什么flock- 我想象一个大问题是如果一个进程在写入文件时终止,或者在释放锁之前?
所以,我已经采用了synthesizerpatel的建议并且使用了sqlite3.如果有人感兴趣的话,我决定直接替换dict它将其条目存储为数据库中的泡菜(我不打算留在内存中,因为数据库访问和酸洗比我正在做的其他事情都要快).我确信有更有效的方法可以做到这一点(我不知道我是否仍然会遇到并发问题),但这里是代码:
from collections import MutableMapping
import sqlite3
import pickle
class PersistentDict(MutableMapping):
def __init__(self, dbpath, iterable=None, **kwargs):
self.dbpath = dbpath
with self.get_connection() as connection:
cursor = connection.cursor()
cursor.execute(
'create table if …Run Code Online (Sandbox Code Playgroud) 我有两个Python脚本,它们都需要定期(想想cronjobs)来调用外部程序.
如果同时调用此程序(我们无法控制),则会发生数据错误,因此我们需要一种方法来同步对此二进制文件的调用.
有没有办法做到这一点,最好只使用Python标准库?
我想读取一个文件,但没有任何锁定。
with open(source, "rb") as infile:
data = infile.read()
Run Code Online (Sandbox Code Playgroud)
上面的代码可以锁定源文件吗?
该源文件可以随时使用新行进行更新(例如在我的脚本运行期间)。我认为不是,因为它仅处于阅读模式(“rb”)。但我发现我们可以使用Windows API来无锁地读取它。我没有找到我的问题的简单答案。
我的脚本在本地运行,但源文件和在其上附加更改的脚本/软件不是(网络驱动器)。
我一直在寻找以下多处理问题的解决方案。
我在 record.py 模块中有一个 Record 类。记录类的职责是处理输入数据并将其保存到 JSON 文件中。Record 类有 put() 方法来更新 JSON 文件。
记录类在类装饰器中初始化。装饰器应用于各个子模块的大多数类。Decorator 提取它所装饰的每个方法的信息,并将数据发送到 Record 类的 put() 方法。Record 类的 put() 方法然后更新 JSON 文件。
问题是当不同的进程运行时,每个进程都会创建自己的记录对象实例,并且由于多个进程尝试更新相同的 json 文件,Json 数据会被损坏。此外,每个进程可能都有运行的线程尝试访问和更新相同的 JSON 文件。请让我知道如何解决这个问题。
class Record():
def put(data):
# read json file
# update json file with new data
# close json file
def decorate_method(theMethod):
# Extract method details
data = extract_method_details(theMethod)
# Initialize record object
rec = Record()
rec.put(data)
class ClassDeco(cls):
# This class decorator decorates all methods of the target class
for …Run Code Online (Sandbox Code Playgroud) 有三个Python程序,写入器程序(writer.py)写入文件output.txt,两个读取器程序同时(reader_1.py, reader_2.py)读取文件。output.txt file
实现这三个程序之间同步的最佳方法是什么? 如果其他程序正在写入输出文件,如何避免读取器程序读取? 如何在Python中有效处理单作者和多读者问题?
我尝试实现fnctl锁定机制,但是在我的python中找不到这个模块。
作家.py
#!/usr/bin/python
import subprocess
import time
cycle = 10
cmd="ls -lrt"
def poll():
with open("/home/output.txt", 'a') as fobj:
fobj.seek(0)
fobj.truncate()
try:
subprocess.Popen(cmd, shell=True, stdout=fobj)
except Exception:
print "Exception Occured"
# Poll the Data
def do_poll():
count = int(time.time())
while True:
looptime = int(time.time())
if (looptime - count) >= cycle:
count = int(time.time())
print('Begin polling cycle')
poll()
print('End polling cycle')
def main():
do_poll()
if __name__ == "__main__": …Run Code Online (Sandbox Code Playgroud) 我在服务器上运行了几个脚本,这些脚本可以对各种字典进行pickle和unpickle.它们都使用相同的基本代码进行酸洗,如下所示:
SellerDict=open('/home/hostadl/SellerDictkm','rb')
SellerDictionarykm=pickle.load(SellerDict)
SellerDict.close()
SellerDict=open('/home/hostadl/SellerDictkm','wb')
pickle.dump(SellerDictionarykm,SellerDict)
SellerDict.close()
Run Code Online (Sandbox Code Playgroud)
除了其中一个脚本外,所有脚本运行正常.有问题的那个去各个网站并擦除数据并将其存储在字典中.这段代码运行一整天的酸洗和解毒词典,并在午夜停止.然后一个cronjob第二天早上又开始了.此脚本可以运行数周而不会出现问题,但是当脚本尝试打开字典时,由于EOFError而导致脚本每月大约一次.字典的大小通常约为80 MB.我甚至尝试在SellerDict.close()之前添加SellerDict.flush()来挑选数据以确保晚上被刷新.
有什么想法可能导致这种情况?Python非常可靠,所以我不认为这是由于文件的大小.在死亡之前代码运行良好很长时间,这让我相信可能在字典中保存了导致此问题的东西,但我不知道.
此外,如果你知道一个更好的方法来保存除了泡菜之外的词典,我愿意接受选择.就像我之前说的那样,词典不断被打开和关闭.只是为了澄清,只有一个程序将使用相同的字典,因此问题不是由试图访问同一字典的几个程序引起的.
更新:
这是我从日志文件中获得的回溯.
Traceback (most recent call last):
File "/home/hostadl/CompileRecentPosts.py", line 782, in <module>
main()
File "/home/hostadl/CompileRecentPosts.py", line 585, in main
SellerDictionarykm=pickle.load(SellerDict)
EOFError
Run Code Online (Sandbox Code Playgroud) 我们有10个Linux盒子,每周必须运行100个不同的任务.当我们在家时,这些计算机主要在晚上工作.我的一位同事正在开发一个项目,通过使用Python自动启动任务来优化运行时间.他的程序将读取任务列表,获取打开的任务,在文件中将该任务标记为正在进行,然后在任务完成后将任务标记为在文件中完成.任务文件将在我们的网络安装上.
我们意识到不建议有多个程序实例访问同一个文件,但我们实际上没有看到任何其他选项.虽然他正在寻找一种方法来阻止两台计算机同时写入文件,但我想出了一种我自己的方法,它比我们在网上找到的方法更容易实现.我的方法是检查文件是否存在,如果不存在则等待几秒钟,然后暂时移动文件.我写了一个脚本来测试这个方法:
#!/usr/bin/env python
import time, os, shutil
from shutil import move
from os import path
fh = "testfile"
fhtemp = "testfiletemp"
while os.path.exists(fh) == False:
time.sleep(3)
move(fh, fhtemp)
f = open(fhtemp, 'w')
line = raw_input("type something: ")
print "writing to file"
f.write(line)
raw_input("hit enter to close file.")
f.close()
move(fhtemp, fh)
Run Code Online (Sandbox Code Playgroud)
在我们的测试中,这种方法有效,但我想知道我们是否会遇到一些我们没有看到的问题.我意识到灾难可能是因为两台计算机同时运行exists().两台计算机不太可能同时达到这一点,因为任务在20分钟到8小时之间.
python ×9
file ×3
windows ×2
concurrency ×1
dictionary ×1
eoferror ×1
file-locking ×1
linux ×1
locking ×1
memoization ×1
networking ×1
persistence ×1
pickle ×1
posix ×1
python-2.7 ×1
python-3.x ×1
winapi ×1