【发布时间】:2023-03-30 15:21:01
【问题描述】:
我写了一个 CGI 脚本。它的子程序之一不能同时执行。即同一用户(或黑客)同时运行两个实例)。我怎样才能避免这种情况?
我使用锁定文件做了以下解决方法,但我不确定它是否安全:
unless (-e $filelock) {
sub_that_should_be_locked();
}
sub sub_that_should_be_locked {
open FILE, ">", $filelock;
flock DATAFILE, LOCK_EX;
close FILE;
...Code that cannot be executed at the same time...
...Code that cannot be executed at the same time...
unlink $filelock;
}
不应该有等待/队列,并发进程不应该调用 sub_that_should_be_locked
【问题讨论】:
-
这仍然容易受到竞争条件的影响。如果两个线程同时到达您的
unless行,那么在错误假设它们是唯一正在运行的副本的情况下,它们都会愉快地继续运行。 -
@ikegami 说你希望“完全避免调用
sub_that_should_be_locked”。对吗? -
是的,“sub_that_should_be_locked”不应该同时运行/被调用,因为这是一个获取资金余额并减去所有资金的例程,如果“sub_that_should_be_locked”同时运行,如我所愿,货币余额将变为负数而不是 0。
-
我们都知道它不应该在多个进程中同时运行。问题是:如果两个进程试图同时运行它会发生什么?第二个进程应该跳过调用
sub_that_should_be_locked,还是应该等待第一个进程退出sub_that_should_be_locked? -
不用等待,第二个进程应该跳过调用
sub_that_should_be_locked,因为余额可能不会更新得这么快,所以几分之一秒也可能导致问题
标签: multithreading perl locking flock