在用
perl
开发一些系统级软件时,经常会遇到文件锁
的
问题。为什么要使用文件锁呢?举一个不是太恰当的例子:(注意,确实是不太恰当,但有助于理解)
这个例子虽然不够恰当,但基本将事情说清楚,需要注意的是LOCK_EX是表示排它锁(Exclude),是独占的,一般用于写操作,而如果换成LOCK_SH(Share)则是共享,多用于读取。有时为了保证多进程对文件的读写都是唯一的,无论读写都进行LOCK_EX的请求。
以下是一段演示程序,名叫flock.pl
[code]
use Fcntl qw(:flock);
use POSIX qw(strftime);
open (FD, " < source.txt") or die "$!\n";
flock(FD, LOCK_EX);
print "Yeah i get the lock by pid=$$ at ", cur_time(), "\n";
sleep 10;
flock(FD, LOCK_UN);
print "Oops i lose the lock by pid=$$ at ", cur_time(), "\n";
close FD;
sub cur_time {
strftime "%H:%M:%S", localtime;
}
[/quote]
使用方法:
打开2个控制台(console),假设分别为A窗口和B窗口,在A命令行下输入:
perl flock.pl
此时会显示:
过2,3秒,在B控制台执行同样的命令:
perl flock.pl
则暂时无任何显示,等到A控制台的程序执行完毕,显示:
的时候,B控制台的程序立刻显示:
过10秒后程序结束并显示:
上述代码及演示说明了排他锁(LOCK_EX)是让多进程串行的对数据源进行操作。注意,这个演示里的source.txt必须是实现存在的!。
街上的柜员机(ATM)同时只能 服务一个人(数据源),而如果有多个人(不同的进程)要取钱,存钱,则会形成冲突,怎么 解决呢?假设柜员机旁边有一个管理员(kernel),柜员机只向持有有效许可(flock,文件锁)的人提供服务,而有效许可只有一份,由管理员发放给申请需要使用ATM的人。
此时假设有A,B,C三个人都要使用柜员机,大家都向管理员提出申请(flock (FH, LOCK_EX) ),管理员根据先后,给最先发请求的人颁发授权(相当于将锁给了这个人),假设是B,此时B获得了授权(flock),可以使用桂员机,他用完之后告诉管理员他用完了(flock(FH, LOCK_UN) ),此时管理员再将授权转交给下一个人A,A又获得了授权(锁,flock),继续使用ATM机器。。。
这个例子虽然不够恰当,但基本将事情说清楚,需要注意的是LOCK_EX是表示排它锁(Exclude),是独占的,一般用于写操作,而如果换成LOCK_SH(Share)则是共享,多用于读取。有时为了保证多进程对文件的读写都是唯一的,无论读写都进行LOCK_EX的请求。
以下是一段演示程序,名叫flock.pl
[code]
use Fcntl qw(:flock);
use POSIX qw(strftime);
open (FD, " < source.txt") or die "$!\n";
flock(FD, LOCK_EX);
print "Yeah i get the lock by pid=$$ at ", cur_time(), "\n";
sleep 10;
flock(FD, LOCK_UN);
print "Oops i lose the lock by pid=$$ at ", cur_time(), "\n";
close FD;
sub cur_time {
strftime "%H:%M:%S", localtime;
}
[/quote]
使用方法:
打开2个控制台(console),假设分别为A窗口和B窗口,在A命令行下输入:
perl flock.pl
此时会显示:
Yeah i get the lock by pid=6122 at 14:20:39
过2,3秒,在B控制台执行同样的命令:
perl flock.pl
则暂时无任何显示,等到A控制台的程序执行完毕,显示:
Oops i lose the lock by pid=6122 at 14:20:49
的时候,B控制台的程序立刻显示:
Yeah i get the lock by pid=6123 at 14:20:49
过10秒后程序结束并显示:
Oops i lose the lock by pid=6123 at 14:20:59
上述代码及演示说明了排他锁(LOCK_EX)是让多进程串行的对数据源进行操作。注意,这个演示里的source.txt必须是实现存在的!。