珀尔 |文件锁定
文件锁定或一般的锁定只是为处理与资源共享相关的问题而提出的各种解决方案之一。
文件锁定是一种保护任何文档的安全性和完整性的方法。文件锁定的主要动机是允许人们提交对文档的更改而不会造成混乱。当一个文件试图由两个或更多用户更改时,可能会出现冲突。
例如,让我们考虑一个包含项目数据的文件。允许整个项目团队修改文件。将在网络上编写一个 CGI 脚本来执行以下操作。
$file = "project.docx";
$commit = $ENV{'QUERY_INFO'};
open(FILE, "$file"); #opening the document
while() {
if (m/^$commit$/) {
print "Change already made\n";
exit;
}
}
close(FILE);
push(@newcommit, $commit);
open(FILE, ">$file");
print ...
close(FILE);
print "Commit made!";
exit;
文件的锁定是在系统级别完成的,这意味着用户不必担心应用锁定的实际细节。引入文件锁是为了对某些文件设置临时限制,以限制它们在不同进程之间的共享方式。根据操作的性质,我们提出了两种类型的锁。第一种是共享锁,另一种是排他锁。对于文件,读访问可以由多个进程共享,因为读访问不会导致共享资源的状态发生任何变化。因此,可以保持共享资源的一致视图。
在 Perl 中,可以使用flock命令完成文件锁定。
flock()
接受两个参数。第一个是文件句柄。第二个参数表示所需的锁定操作。语法:
flock [FILEHANDLE], [OPERATION]
这里, OPERATION是一个数值,它可以是1 、 2 、 4或8 。
这些数值具有不同的含义,用于执行不同的操作,例如:
- LOCK_SH
- LOCK_EX
- LOCK_NB
- LOCK_UN
Perl 使用数字来表示值:
sub LOCK_SH { 1 } ## set as shared lock
sub LOCK_EX { 2 } ## set as exclusive lock
sub LOCK_NB { 4 } ## set lock without any blocks
sub LOCK_UN { 8 } ## unlock the FILEHANDLE
- 共享锁:
当您只想读取文件并允许其他人同时读取同一文件时,可以应用共享锁。 Shared Lock 不仅设置了一个锁,而且它首先检查其他锁的存在。此锁不涵盖所有锁的存在检查,而仅适用于“独占锁”。如果存在排他锁,它会一直等到锁被删除。删除后,它将作为共享锁执行。可能同时存在多个共享锁。语法:
flock(FILE, 1); #from the above code
- 专属锁
当文件要在一群人之间使用时使用排他锁,并且每个人都有权进行更改。文件上只有一个排他锁,因此一次只有一个用户/进程进行更改。在排他锁中,规则是“我是唯一的”。 flock() 在脚本中查找任何其他类型的锁。如果找到,它将保留,直到所有这些都从脚本中删除。在适当的时候,它将锁定文件。语法:
flock(FILE, 2); #from the above code
- 非阻塞锁
非阻塞锁通知系统不要等待其他锁脱离文件。如果在文件中找到另一个锁,它将返回错误消息。语法:
flock(FILE, 4); #from the above code
- 解锁
取消阻止任何指定的文件 - 与 close(FILE)函数一样。语法:
flock(FILE, 8); #from the above code
下面讨论的是一个解释flock()函数使用的问题:问题:
上面示例中解释的脚本的主要问题是当它打开文件时 - project.docx ,清除第一个文件并使其为空。
想象一下,A、B、C 人试图在几乎相同的时间提交。人员 A 打开文件以检查数据。关闭它,然后开始编辑数据。 (清除第一个文件)
同时,B 人打开文件进行检查/阅读,发现它完全是空的。那是冲突!整个系统都会被打乱。
解决方案:
这是使用文件锁定的地方。 A、B、C 人愿意对文档做出承诺。人 A 打开文件,那一刻(共享锁被激活),检查文件内的所有数据并再次关闭它(解锁文件)。
然后,A 人希望提交对文件的更改并重新打开文件进行编辑(这是独占锁生效的时候)。当 A 人对文件进行更改时,B 人或 C 人都无法打开文件进行读取或写入。人 A 做他的工作,关闭文件(解锁)。
现在,如果人 B 在此期间试图打开文件,将会得到一个错误 - “文件正在被其他候选人访问”。
这样就不会造成脚趾踩踏,并保持良好的工作流程。羊群()与lockf()
lockf()
函数用于锁定文件的一部分,而不像flock() 一次锁定整个文件。 lockf() 不能直接在 perl 中使用,而 Perl 本身支持 flock 系统调用,但不适用于网络锁。
Perl 还支持fcntl()系统调用,它提供了 Perl 中最多的锁定控制。