【通过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;释放信号量则相反。