我在用着SSHFS在一台机器上运行某个进程并将结果存储在另一台机器上。
我用来安装的命令是sshfs user@host:/rempte/path /local/path
。
如果文件不存在,我正在运行的脚本会在挂载点内的文件夹中创建一个具有特定名称的文件,然后开始工作并最终保存内容。如果文件已经存在,它会跳过它并转到下一个文件。之后,它会转到下一个文件名。
为了将工作分散到所有 CPU 核心上,我运行了与 CPU 上的线程一样多的进程实例。
Python 函数如下:
def create(fname):
if os.path.exists(fname):
return True
else:
open(fname, 'a').close()
return False
有时会发生的情况是,两个或多个脚本实例会create
同时进入该函数并最终执行相同的工作,这非常浪费时间。
我的问题是:有什么办法可以解决这个问题吗?要么通过某种 ssh 参数,要么通过对我的 Python 代码进行一些更改。
使脚本多线程化目前超出了我的范围。
答案1
比赛在存在性检查和 open() 之间——为了避免这种情况,最好的方法是不做手动预检,而是让操作本身来完成。
open() 函数确实有一个“原子创建”模式"x"
(或低级 libc 函数中的 O_CREAT|O_EXCL,在 sshfs 中以 1:1 转换为 SFTP 打开标志)。最直接的代码重写将是:
def create(name):
try:
open(fname, 'x').close()
return False
except FileExistsError:
return True
try:
with open(fname, 'x') as outf:
do_processing(outf)
except FileExistsError:
pass
另一种方法是将整个create()
函数包装在某个跨进程同步(锁或互斥)中,以便一次只有一个进程可以调用该函数。大多数操作系统支持几种类型的“全局”同步机制;例如,任何文件都可以通过 充当锁fcntl.flock()
。