日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

flock

發(fā)布時(shí)間:2023/12/19 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 flock 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

shell命令flock通過(guò)加鎖方式實(shí)現(xiàn)互斥訪問(wèn)。常用于多進(jìn)程間互斥訪問(wèn)。flock用flock(2)系統(tǒng)調(diào)用實(shí)現(xiàn)。

Linux提供了flock(對(duì)整個(gè)文件加鎖)、fcntl(對(duì)整個(gè)文件區(qū)域加鎖)兩個(gè)函數(shù)來(lái)做進(jìn)程間的文件同步。

同時(shí)也可以使用信號(hào)量來(lái)完成所需的同步,但通常使用文件鎖會(huì)更好一些,因?yàn)閮?nèi)核能夠自動(dòng)將鎖與文件關(guān)聯(lián)起來(lái)。

flock 是對(duì)于整個(gè)文件的建議性鎖。也就是說(shuō),如果一個(gè)進(jìn)程在一個(gè)文件(inode)上放了鎖,那么其它進(jìn)程是可以知道的。(建議性鎖不強(qiáng)求進(jìn)程遵守。)

最棒的一點(diǎn)是,flock(2)第一個(gè)參數(shù)是文件描述符,在此文件描述符關(guān)閉時(shí),鎖會(huì)自動(dòng)釋放。而當(dāng)進(jìn)程終止時(shí),所有的文件描述符均會(huì)被關(guān)閉。于是,很多時(shí)候就不用考慮解鎖的事情。

用法

       flock [-sxon] [-w timeout] lockfile [-c] command...

       flock [-sxon] [-w timeout] lockdir [-c] command...

       flock [-sxun] [-w timeout] fd

參數(shù)

-s: 獲取共享鎖,有時(shí)被稱(chēng)為只讀鎖。在定向?yàn)槟澄募腇D上設(shè)置共享鎖而未釋放鎖的時(shí)間內(nèi),其他進(jìn)程試圖在定向?yàn)榇宋募腇D上設(shè)置獨(dú)占鎖的請(qǐng)求失敗,而其他進(jìn)程試圖在定向?yàn)榇宋募腇D上設(shè)置共享鎖的請(qǐng)求會(huì)成功。

-x,-e:獲取互斥鎖,有時(shí)稱(chēng)為寫(xiě)鎖,默認(rèn)。在定向?yàn)槟澄募腇D上設(shè)置獨(dú)占鎖而未釋放鎖的時(shí)間內(nèi),其他進(jìn)程試圖在定向?yàn)榇宋募腇D上設(shè)置共享鎖或獨(dú)占鎖都會(huì)失敗。

-u:釋放鎖。這個(gè)不是必須的,當(dāng)文件關(guān)閉時(shí)(進(jìn)程結(jié)束后,進(jìn)程文件都被關(guān)閉)鎖被自動(dòng)釋放。但是,特殊情況下是必須的,例如受鎖保護(hù)的命令行fork一個(gè)后臺(tái)進(jìn)程,此進(jìn)程不應(yīng)該持有鎖。

Drop a lock. This is usually not required, since a lock is automatically dropped when the
file is closed. However, it may be required in special cases, for example if the enclosed
command group may have forked a background process which should not be holding the lock.
-n:非阻塞,獲取鎖失敗后立刻返回,退出碼1。

-w:seconds,等待超時(shí)。

-o:在執(zhí)行命令前,關(guān)閉被鎖文件的文件描述符。這是有用的,當(dāng)時(shí)命令行fork一個(gè)子進(jìn)程,該子進(jìn)程不應(yīng)該持有鎖。

-c:傳遞一個(gè)單獨(dú)command給shell(在新shell進(jìn)程中執(zhí)行命令)。-c選項(xiàng)表示,如果成功鎖定,則執(zhí)行其后用雙引號(hào)括起的命令,如果是多個(gè)命令,可以用分號(hào)分隔。

flock file -c command 等價(jià)于flock file sh -c command,前者flock用-c創(chuàng)建進(jìn)程執(zhí)行command,后者flock執(zhí)行sh命令,sh命令創(chuàng)建進(jìn)程執(zhí)行命令command。

描述

該命令管理flock(2) locks為shell scripts或the command line。

第一或第二種形式在命令執(zhí)行時(shí)回繞鎖。它鎖住指定文件或路徑(若不存在創(chuàng)建它)。

第三種形式在腳本中應(yīng)用方便,形式如下

       (
         flock -n 9 || exit 1
         # ... commands executed under lock ...
       ) 9>/var/lock/mylockfile

The mode used to open the file doesn't matter to flock; using > or >> allows the lockfile to be created if it does not already exist,however, write permission is required.

using < requires that the file already exists but only read permission is required.

默認(rèn)情況下,flock會(huì)阻塞等,直到獲取鎖。

flock(2)中描述

Locks created by flock() are associated with an open file table entry. This means that duplicate
file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock
may be modified or released using any of these descriptors. Furthermore, the lock is released
either by an explicit LOCK_UN operation on any of these duplicate descriptors, or when all such
descriptors have been closed.

如果通過(guò)一個(gè)特定的文件描述符獲取了一個(gè)鎖并且創(chuàng)建了該描述符的一個(gè)或多個(gè)副本,那么,如果不顯示的調(diào)用一個(gè)解鎖操作,只有當(dāng)文件描述符副本都被關(guān)閉了之后鎖才會(huì)被釋放。

通過(guò)fork()創(chuàng)建的鎖在exec()中會(huì)得以保留(除非在文件描述符上設(shè)置了close-on-exec標(biāo)記并且該文件描述符是最后一個(gè)引用底層的打開(kāi)文件描述的描述符)。

應(yīng)用

1 crontab運(yùn)用flock防止重復(fù)執(zhí)行

* * * * * (flock -xn ./test.lock -c "sh /root/test.sh") #-n 為非阻塞模式

2 機(jī)器down機(jī)自動(dòng)啟動(dòng)或重啟

可以在daemon開(kāi)始的時(shí)候, 打開(kāi)一個(gè)文件然后獲取一個(gè)寫(xiě)鎖. 守護(hù)腳本也打開(kāi)文件并設(shè)置寫(xiě)鎖, 然后阻塞, 一旦寫(xiě)鎖獲得成功, 則說(shuō)明daemon已經(jīng)掛了. 此時(shí)守護(hù)腳本重啟daemon并放棄寫(xiě)鎖.

flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式

運(yùn)行中... 再次執(zhí)行

flock -x ./test.lock -c "/usr/local/nginx/sbin/nginx" #去掉-n表示使用阻塞模式

阻塞中...

模擬down機(jī)

[root@localhost ~]# ps aux |grep "nginx"|grep"master"|grep -v "grep"|awk'{print $2}'|xargskill -9 

kill后阻塞的命令馬上執(zhí)行 新的進(jìn)程PID立馬產(chǎn)生。

3. flock執(zhí)行多條命令

#!/bin/sh

echo "pid is $$"

flock wang sh -c " echo $$ ; 
while [ 1 ] ;
do 
echo wangt ;
echo $$ ;
sleep 1; 
done ; "

echo "exec over"
exit 0

該進(jìn)程執(zhí)行會(huì)產(chǎn)生同時(shí)存在的三個(gè)進(jìn)程:1)腳本本身啟動(dòng)進(jìn)程;2)執(zhí)行flock時(shí),flock語(yǔ)句本身作為子進(jìn)程運(yùn)行,父進(jìn)程阻塞等待flock進(jìn)程結(jié)束;

3)flock的參數(shù)sh開(kāi)啟一個(gè)子進(jìn)程執(zhí)行后面的命令(有無(wú)sh都會(huì)開(kāi)啟新進(jìn)程執(zhí)行命令)。

1)進(jìn)程阻塞等待2)進(jìn)程;2)進(jìn)程阻塞等待3)進(jìn)程;3)進(jìn)程永不退出,所以一直打印進(jìn)程號(hào)(注意,打印的進(jìn)程號(hào)為1)進(jìn)程號(hào),即$$都為1)進(jìn)程號(hào)),不會(huì)打印“exec over”。

若此時(shí)該腳本再被調(diào)用執(zhí)行,則會(huì)同時(shí)再出現(xiàn)兩個(gè)進(jìn)程:1)和2),進(jìn)程2)忙等文件鎖(獲取鎖后才執(zhí)行后面的命令)。

flock第三種形式應(yīng)用

flock可以接收文件描述符參數(shù)。這種方法在 shell 腳本里特別有用。比如如下代碼:

lockit () {
  exec 7<>.lock
  flock -n 7 || {
    echo "Waiting for lock to release..."
    flock 7
  }
}

exec行打開(kāi).lock文件為7號(hào)文件描述符,然后拿 flock 嘗試鎖它。如果失敗了,就輸出一條消息,并且等待鎖被釋放。那個(gè)7號(hào)文件描述符就讓它一直開(kāi)著了,反正腳本執(zhí)行完畢內(nèi)核會(huì)釋放,也不用去調(diào)用trap內(nèi)建命令了。

上邊有一點(diǎn)很有意思的是,flock 是一個(gè)子進(jìn)程,但是因?yàn)槲募枋龇?fork 和 execve 中會(huì)共享,而 flock 鎖在 fork 和 execve 時(shí)也不會(huì)改變,所以子進(jìn)程在那個(gè)文件描述符上加鎖后,即使它退出了,因?yàn)槟莻€(gè)文件描述符父進(jìn)程還有一份,所以不會(huì)被關(guān)閉,鎖也就得以保留。(所以,如果余下的腳本里要是有進(jìn)程帶著那個(gè)文件描述符fork 到后臺(tái)鎖就不會(huì)在腳本執(zhí)行完后自動(dòng)解除啦……)

----鎖不會(huì)被釋放

#!/bin/bash

{
     flock –n 3
     [$? –eq 1] && { echo fail ;exit}
     echo succeed
     #Doyour task here …

} 3 <> mylockfile

首先使用<>打開(kāi)mylockfile 并定向到文件描述符3,而定向文件描述符是先于命令執(zhí)行的,因此假如要執(zhí)行的語(yǔ)句段中需要讀寫(xiě)mylockfile文件,例如想獲得上一個(gè)腳本實(shí)例的 pid,并將此次的腳本實(shí)例的pid寫(xiě)入mylockfile。此時(shí)直接用>打開(kāi)mylockfile會(huì)清空上次存入的內(nèi)容,而用<打開(kāi) mylockfile當(dāng)它不存在時(shí)會(huì)導(dǎo)致一個(gè)錯(cuò)誤。

其次,以非阻塞的方式打開(kāi)mylockfile,flock –n 3,其中3是mylockfile的文件描述符,若能夠正常獲取鎖(默認(rèn)是排它鎖),則繼續(xù)往下執(zhí)行,否則返回1,該返回碼能夠在接下來(lái)的語(yǔ)句中[ $? –eq 1 ] 進(jìn)行判斷,若為1,則輸出失敗并退出當(dāng)前腳本。

參考:

1. flock——Linux 下的文件鎖

2. 每天進(jìn)步一點(diǎn)點(diǎn)——Linux編程中的文件鎖之flock

3. 從flock引發(fā)的一個(gè)bug談起(1) 進(jìn)程的文件描述符

總結(jié)

以上是生活随笔為你收集整理的flock的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。