如何在Linux中使用flock控制程序的异步执行
最近我常常需要同时ssh给若干台电脑做许多需要等待,而且可以同时进行的工作。例如:
1.让远端电脑同时更新套件
2.同时传送小档案给远端的电脑(时间大部分在ssh认证)
然而之后的动作又需要在确认上述工作完毕之后,才能继续进行。
过去我都是这样做:
#前面的工作 update_pkg_on_machine_1 update_pkg_on_machine_2 update_pkg_on_machine_3 #...后面的工作
这样虽然可以确保工作同时进行完毕,但是就是很慢…
另一种可能的方法是:
#前面的工作 update_pkg_on_machine_1& update_pkg_on_machine_2& update_pkg_on_machine_3& sleep10 #...后面的工作
这样子虽然可以同时进行工作,但是如果10秒内工作还没完成,接下来的工作可能就会出错了。
而工作要在多少秒之内做完,其实是很难掌握的。
利用flock来管理工作状态
我过去在自修作业系统的时候,有学到mutex这个东西,而flock就是可以在shell上使用的mutex。
flock的官方说明
NAME flock-Managelocksfromshellscripts SYNOPSIS flock[-sxon][-wtimeout]lockfile[-c]command... flock[-sxon][-wtimeout]lockdir[-c]command... flock[-sxun][-wtimeout]fd DESCRIPTION Thisutilitymanagesflock(2)locksfromwithinshellscriptsorthe commandline. Thefirstandsecondformswrapsthelockaroundtheexecutinga command,inamannersimilartosu(1)ornewgrp(1).Itlocksa specifiedfileordirectory,whichiscreated(assumingappropriate permissions),ifitdoesnotalreadyexist. Thethirdformisconvenientinsideshellscripts,andisusuallyused thefollowingmanner: ( flock-s200 #...commandsexecutedunderlock... )200>/var/lock/mylockfile Themodeusedtoopenthefiledoesn'tmattertoflock;using>or>> allowsthelockfiletobecreatedifitdoesnotalreadyexist, however,writepermissionisrequired;using<requiresthatthefile alreadyexistsbutonlyreadpermissionisrequired. Bydefault,ifthelockcannotbeimmediatelyacquired,flockwaits untilthelockisavailable. OPTIONS -s,--shared Obtainasharedlock,sometimescalledareadlock. -x,-e,--exclusive Obtainanexclusivelock,sometimescalledawritelock.This isthedefault. -u,--unlock Dropalock.Thisisusuallynotrequired,sincealockis automaticallydroppedwhenthefileisclosed.However,itmay berequiredinspecialcases,forexampleiftheenclosed commandgroupmayhaveforkedabackgroundprocesswhichshould notbeholdingthelock. -n,--nb,--nonblock Fail(withanexitcodeof1)ratherthanwaitifthelock cannotbeimmediatelyacquired. -w,--wait,--timeoutseconds Fail(withanexitcodeof1)ifthelockcannotbeacquired withinsecondsseconds.Decimalfractionalvaluesareallowed. -o,--close Closethefiledescriptoronwhichthelockisheldbefore executingcommand.Thisisusefulifcommandspawnsachild processwhichshouldnotbeholdingthelock. -c,--commandcommand Passasinglecommandtotheshellwith-c. -h,--help Printahelpmessage. AUTHOR WrittenbyH.PeterAnvin<hpa@zytor.com>. COPYRIGHT Copyright©2003-2006H.PeterAnvin. Thisisfreesoftware;seethesourceforcopyingconditions.Thereis NOwarranty;notevenforMERCHANTABILITYorFITNESSFORAPARTICULAR PURPOSE. SEEALSO flock(2) AVAILABILITY Theflockcommandispartoftheutil-linux-ngpackageandisavailable fromftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
重点说明
透过flock,程序会先尝试取得某个lock(通常代表某个档案)的拥有权之后才执行,执行的时候会握有该lock的拥有权,并且在结束之后才释出拥有权。
举例来说,如果我们写一个shellscript放在$HOME底下:
#!/bin/bash sleep10 date
储存成test.sh并且打开执行权限(chmod700test.sh)
此时如果我们打开两个shell,并且约同时执行:
flock/tmp/demo.lock~/test.sh
这时会发生什麽事情呢?
使用者应该会看到两个shell都停住,一个等10秒后印出时间,一个再过10秒后印出时间:
A
wush@router:~$flock/tmp/demo.lock./test.sh
B
wush@router:~$flock/tmp/demo.lock./test.sh
其中A程序先抢到/tmp/demo.lock的拥有权,然后执行test.sh。而B程序等到A程序结束之后(A归还/tmp/demo.lock的拥有权),才拿到/tmp/demo.lock的拥有权。所以B程序自然比A程序慢10秒。
flock的参数
除了预设的行为之外,我们可以透过参数来调整flock的行为。和预设行为上最主要的差异在于,当无法获得lock_path的拥有权时,接下来的动作会不同。
1.flock-nlock_pathxxx:当无法获得拥有权的时候,直接中止程序,不执行xxx。
2.flock-slock_pathxxx:把lock_path当成一个sharedlock,同时能被多个程序拥有。所以大家都可以马上执行,而且同时拥有lock_path
3.flock-xlock_pathxxx:把lock_path当成一个exclusivelock,同时只能被一个程序拥有。
注:一个lock_path不能同时为shared和exclusive!
解决简介中的问题
所以透过组合flock,我可以同时执行若干个工作,并且等到他们结束之后再继续执行接下来的工作:
#前面的工作 flock-slock_pathupdate_pkg_on_machine_1& flock-slock_pathupdate_pkg_on_machine_2& flock-slock_pathupdate_pkg_on_machine_3& flock-xlock_pathecho"alldone!" #...后面的工作
关键在于flock-xlock_pathxxx会因为shared和exclusive互斥的关系,而不能共存。因此就会等到上面的工作都结束(归还lock_path的拥有权)之后才执行。
以上就是在Linux上使用flock命令控制程序的异步执行的全部内容,有需要的朋友们可以参考学习。