關(guān)于forck
- flock 是對(duì)于整個(gè)文件的建議性鎖。也就是說,如果一個(gè)進(jìn)程在一個(gè)文件(inode)上放了鎖,那么其它進(jìn)程是可以知道的欺嗤。(建議性鎖不強(qiáng)求進(jìn)程遵守。)最棒的一點(diǎn)是卫枝,它的第一個(gè)參數(shù)是文件描述符煎饼,在此文件描述符關(guān)閉時(shí),鎖會(huì)自動(dòng)釋放校赤。而當(dāng)進(jìn)程終止時(shí)吆玖,所有的文件描述符均會(huì)被關(guān)閉。
應(yīng)用場(chǎng)景
linux的crontab命令马篮,可以定時(shí)執(zhí)行操作沾乘,最小周期是每分鐘執(zhí)行一次。現(xiàn)在有個(gè)問題浑测,如果設(shè)定了任務(wù)每2分鐘執(zhí)行一次翅阵,但有可能執(zhí)行該任務(wù)需要花費(fèi)10分鐘,這時(shí)系統(tǒng)會(huì)再執(zhí)行任務(wù)。導(dǎo)致兩個(gè)相同的任務(wù)在執(zhí)行掷匠。這種情況下可能會(huì)出現(xiàn)一些并發(fā)問題读慎,嚴(yán)重時(shí)會(huì)導(dǎo)致出現(xiàn)臟數(shù)據(jù)/性能瓶頸的惡性循環(huán)。
通過使用flock建立排它鎖可以規(guī)避這個(gè)問題槐雾,如果一個(gè)進(jìn)程對(duì)某個(gè)加了排他鎖夭委,則其它進(jìn)程無法加鎖,可以選擇等待超時(shí)或馬上返回募强。
- 例如
cat /opt/sleep.sh
#!/bin/bash
# Description: test for file flock
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo ""
echo "----------------------------------"
echo "start at `date '+%Y-%m-%d %H:%M:%S'` ..."
sleep 600s
echo "finished at `date '+%Y-%m-%d %H:%M:%S'` ..."
- 設(shè)置計(jì)劃任務(wù)每2分鐘執(zhí)行
2/* * * * * /opt/sleep.sh >> /tmp/sleep.log
而實(shí)際情況是10分鐘后我們查看進(jìn)程ps aux|grep sleep.sh 可以看到有5個(gè)進(jìn)程在運(yùn)行,我們則希望執(zhí)行完上一任務(wù)株灸,再執(zhí)行下一任務(wù),如果上一任務(wù)未執(zhí)行完成擎值,則這次的任務(wù)不執(zhí)行慌烧,直到下一周期再判斷,如果上一任務(wù)執(zhí)行完成鸠儿,則可以執(zhí)行下一任務(wù)屹蚊。
改進(jìn)方法
我們可以使用一個(gè)鎖文件,來記錄任務(wù)是否執(zhí)行中进每。
首先判斷/tmp/sleep.lock是否存在汹粤,如果不存在,則創(chuàng)建田晚,然后執(zhí)行任務(wù)嘱兼,任務(wù)執(zhí)行完后刪除鎖文件。如果鎖文件已經(jīng)存在贤徒,則退出這次的任務(wù)芹壕。這樣的確可以保證任務(wù)執(zhí)行其間不會(huì)有新任務(wù)執(zhí)行,但這樣需要在任務(wù)文件中寫代碼做判斷接奈,不方便踢涌。能不能把任務(wù)鎖定的判斷放在任務(wù)以外呢?
使用linux flock 文件鎖實(shí)現(xiàn)任務(wù)鎖定序宦,解決沖突
格式
flock [-sxun][-w #]
flock [-sxon][-w #] file [-c] command
選項(xiàng)
-s, --shared: 獲得一個(gè)共享鎖
-x, --exclusive: 獲得一個(gè)獨(dú)占鎖/排他鎖
-u, --unlock: 移除一個(gè)鎖睁壁,通常是不需要的,腳本執(zhí)行完會(huì)自動(dòng)丟棄鎖
-n, --nonblock: 如果沒有立即獲得鎖挨厚,直接失敗而不是等待
-w, --timeout: 如果沒有立即獲得鎖堡僻,等待指定時(shí)間
-o, --close: 在運(yùn)行命令前關(guān)閉文件的描述符號(hào)。用于如果命令產(chǎn)生子進(jìn)程時(shí)會(huì)不受鎖的管控
-c, --command: 在shell中運(yùn)行一個(gè)單獨(dú)的命令
-h, --help 顯示幫助
-V, --version: 顯示版本
-w 等待時(shí)間,秒
獨(dú)占鎖/排他鎖
- 設(shè)置鎖
使用計(jì)劃任務(wù)執(zhí)行sleep.sh疫剃,文件鎖使用獨(dú)占鎖,如果鎖定則失敗不等待硼讽。這樣當(dāng)任務(wù)未執(zhí)行完成巢价,下一任務(wù)判斷到/tmp/mytest.lock被鎖定,則結(jié)束當(dāng)前的任務(wù),下一周期再判斷壤躲。參數(shù)為-xn
2/* * * * * flock -xn /tmp/sleep.lock -c /opt/sleep.sh >> /tmp/sleep.log
- 創(chuàng)建獨(dú)占鎖/排他鎖城菊,加上等待超時(shí)/秒
啟動(dòng)的定時(shí)任務(wù)等待了20秒后,上一個(gè)任務(wù)釋放了鎖碉克,任務(wù)可以馬上拿到鎖凌唬,并繼續(xù)執(zhí)行
2/* * * * * flock -x -w 20 /tmp/sleep.lock -c /opt/sleep.sh >> /tmp/sleep.log