【通過fifo實作信号量】
利用fifo的block-reading實作。
#!/bin/bash
conf_max_currency=10
conf_sem_file=/tmp/$.fifo
conf_fifo_fd=123 # 123 for example, or any expect 0,1,2
# init
mkinfo ${conf_sem_file}
exec ${conf_fifo_fd}<>${conf_sem_file}
rm ${conf_sem_file}
for (( i = 0; i < ${conf_max_currency}; i++ ))
do
echo
done >&${conf_fifo_fd}
for ((i = 0; i < 1000; ++i))
do
read -u ${conf_fifo_fd} # block if nothing in fifo
{
# do your job here
echo # write to fifo means free sem
} >&${conf_fifo_fd}
done
【通過flock+檔案實作互斥和信号量】
假設worker.sh為處理腳本(下同)
1、在排程worker.sh時(也就是worker.sh的外層)互斥,可以簡單的通過flock實作。
優點:
将worker的邏輯與鎖過程解耦
缺點:
需要統一的入口排程worker.sh
flock /path/to/lock-file work.sh
2、在worker.sh内實作互斥
檔案lockfile.lock記錄目前的鎖curlock(唯一表示一個鎖的特性值,如pid),通過flock實作lockfile.lock的互斥修改。
加鎖過程:
1)flock讀取目前鎖curlock,curlock為空,記錄特性鎖到所檔案lockfile.lock,否則重複讀取目前鎖curlock并驗證的過程。
2)鎖擷取後即傳回狀态;鎖逾時或失敗則可以相應的定義傳回。
解鎖過程:
與加鎖過程類似,隻是進行相反的過程。
簡單的執行個體如下:
#!/bin/bash
config_lock_file="/tmp/xx_lock_file.lock"
config_free_lock="FREE"
if [ ! -f ${config_lock_file} ];then
echo ${config_free_lock} > ${config_lock_file}
fi
function mutex_lock()
{
local lock_name=$1
if [ "x${lock_name}" = "x" ];then
lock_name=$
fi
flock ${config_lock_file} echo > /dev/null && while curlock=`cat ${config_lock_file}`; do if [ "${curlock}" = "${config_free_lock}" -o "${curlock}" = "$
{lock_name}" ];then echo ${lock_name} > ${config_lock_file}; break; fi ; done
echo "${lock_name}"
return 0
}
function mutex_unlock()
{
local lock_name=$1
if [ "x${lock_name}" = "x" ];then
lock_name=$
fi
flock ${config_lock_file} echo > /dev/null && curlock=`cat ${config_lock_file}` && if [ "${curlock}" = "${lock_name}" ];then echo ${config_free_lock} > $
{config_lock_file}; fi
return 0
}
上面的例子很簡單,需要處理的問題還有很多:
1)例子中鎖是持久的、強制的,lock、unlock出現不比對的情況下,就是杯具,是以要考慮到lock之後沒有unlock的情況。比如,通過限制鎖的最長有效期(可以簡單的通過lockfile.lock的mtime判斷),過期的鎖等價于FREE
2)性能消耗
3)try_lock實作
3、實作信号量
基于上面的例子,實作信号兩就比較簡單了,之間将寫入所檔案的内容置為目前的信号數量,每擷取一個信号就将檔案中的數字減小1;釋放信号量則相反。