确保只有给定脚本的一个实例运行的最简单/最好的方法是什么 - 假设它是Linux上的Bash?
目前我正在做:
ps -C script.name.sh > /dev/null 2>&1 || ./script.name.sh
Run Code Online (Sandbox Code Playgroud)
但它有几个问题:
-C 仅检查进程名称的前14个字符当然,我可以编写自己的pidfile处理,但我觉得应该有一个简单的方法来实现它.
关于那个线程: bash flock:如果无法获取锁定则退出
如果有人能向我解释'200'代表什么,我将不胜感激.
我已经阅读了关于flock的内容,如果要指定文件描述符,似乎有200个,但这个数字有什么好处呢?
我正在将flock()用于进程间命名的互斥锁(即某些进程可以决定对"some_name"进行锁定,这是通过在temp目录中锁定名为"some_name"的文件来实现的:
lockfile = "/tmp/some_name.lock";
fd = open(lockfile, O_CREAT);
flock(fd, LOCK_EX);
do_something();
unlink(lockfile);
flock(fd, LOCK_UN);
Run Code Online (Sandbox Code Playgroud)
应该在某个时候删除锁定文件,以避免使用数百个文件填充临时目录.
但是,此代码中存在明显的竞争条件; 进程A,B和C的示例:
A opens file
A locks file
B opens file
A unlinks file
A unlocks file
B locks file (B holds a lock on the deleted file)
C opens file (a new file one is created)
C locks file (two processes hold the same named mutex !)
Run Code Online (Sandbox Code Playgroud)
有没有办法在某些时候删除锁定文件而不引入这种竞争条件?
我需要每分钟运行一个python脚本(job.py).如果该脚本已在运行,则不得启动该脚本.它的执行时间可能在10秒到几个小时之间.
所以我放入我的crontab:
* * * * * root cd /home/lorenzo/cron && python -u job.py 1>> /var/log/job/log 2>> /var/log/job/err
Run Code Online (Sandbox Code Playgroud)
为了避免在脚本运行时启动脚本,我使用flock().
这是脚本(job.py):
import fcntl
import time
import sys
def doIncrediblyImportantThings ():
for i in range (100):
sys.stdout.write ('[%s] %d.\n' % (time.strftime ('%c'), i) )
time.sleep (1)
if __name__ == '__main__':
f = open ('lock', 'w')
try: fcntl.lockf (f, fcntl.LOCK_EX | fcntl.LOCK_NB)
except:
sys.stderr.write ('[%s] Script already running.\n' % time.strftime ('%c') )
sys.exit (-1)
doIncrediblyImportantThings ()
Run Code Online (Sandbox Code Playgroud)
这种方法似乎有效.
有什么我想念的吗?我可以使用这种方法遇到任何麻烦吗?
是否有更多建议或"正确"的方法来实现这种行为?
我感谢你的任何建议.
以下锁定机制用于防止cron作业并发运行:
#!/bin/bash
echo "Before critical section"
(
flock -e 200
echo "In critical section"
sleep 5
) 200>/tmp/blah.lockfile
echo "After critical section"
Run Code Online (Sandbox Code Playgroud)
当一起运行两个实例时,后者一直等到第一个完成,然后运行.这可能导致等待运行的脚本积压.
如何更改此脚本以便在flock无法获取锁定时终止脚本?我试过-n没有成功.
fopen()如果文件存在但是当前被锁定,则会失败LOCK_EX吗?
或者我是否必须打开它,然后尝试设置锁定,以确定是否已存在?
我也读过那flock()会;
暂停[脚本]直到你无限期地获得锁定或直到你的脚本超时
如果是这样,那么'暂停'是否可以绕过;
if (!flock($f, LOCK_SH | LOCK_NB)) {
// file locked, do something else
}
Run Code Online (Sandbox Code Playgroud) 在Bash中,我试图使函数getLock与不同的锁名称一起使用.
function getLock
{
getLock_FILE="${1}"
getLock_OP="${2}"
case "${getLock_OP}" in
"LOCK_UN")
flock -u "${getLock_FILE}"
rm -fr "${getLock_FILE}"
;;
"LOCK_EX")
flock -x "${getLock_FILE}"
esac
}
Run Code Online (Sandbox Code Playgroud)
但是弗洛克说 flock: bad number: myfilelock
我怎样才能锁定文件,并在需要时释放它,而不必在flock中执行命令?
它是这样使用的:
getLock myfilelock LOCK_EX
somecommands
........
getLock myfilelock LOCK_UN
Run Code Online (Sandbox Code Playgroud) 我构建了一个[widget] [1],它从Safari中最前面的窗口抓取URL,然后允许你使用tr.im API缩短它.工作甜美如.
我想让它更灵活,所以我正在研究如何从其他浏览器中获取URL.这是在Safari中运行的AppleScript:
tell application "Safari"
return URL of front document as string
end tell
Run Code Online (Sandbox Code Playgroud)
经过一番挖掘后,我确定以下内容可能适用于Firefox(虽然有人告诉我它对他不起作用,可能与某些扩展冲突?):
tell application "Firefox"
set myFirefox to properties of front window as list
return item 3 of myFirefox
end tell
Run Code Online (Sandbox Code Playgroud)
注意:上面是一个不太好的做法的例子,依赖于列表项的位置.请参阅下面的Firefox更好的解决方案.
我想做的是在这里建立一个列表,列出Mac上每个现代浏览器的最终等价物:Opera,Camino,Flock等.
更新:在我对这个主题的研究中,我在MacOSXHints.com上遇到了一个有用的主题.我下面的大部分答案都是基于这个讨论.
更新2:我已将此页面上的AppleScript合并到[widget] [1]中.它似乎工作膨胀.
flock()是PHP的便携式咨询文件锁定功能.他们明确宣传它甚至可以在windows下运行:
flock()允许您执行一个简单的读/写模型,几乎可以在每个平台上使用(包括大多数Unix衍生产品甚至Windows).
我想在阻塞上设置一个便携式超时flock()(并且没有忙于等待处理该LOCK_NB选项).在UNIX中,这可以简单地通过设置警报来实现,该警报将发送SIGALRM:
pcntl_signal(SIGALRM, function() {});
pcntl_alarm(3);
try {
if (!flock($handle, LOCK_EX)) {
throw new \Exception("Timeout");
}
} finally {
pcntl_alarm(0);
pcntl_signal_dispatch();
pcntl_signal(SIGALRM, SIG_DFL);
}
Run Code Online (Sandbox Code Playgroud)
是否有可移植的方法来阻止阻塞flock()?如果是这样,怎么样?
PHP的文档页面flock()表明在IIS下使用它是不安全的.如果我不能flock在任何情况下都依赖,还有另一种方法可以安全地实现同样的目的吗?
flock ×10
bash ×3
php ×3
file-locking ×2
linux ×2
applescript ×1
c ×1
camino ×1
concurrency ×1
cron ×1
filelock ×1
filesystems ×1
firefox ×1
lockfile ×1
locking ×1
pid ×1
python ×1
safari ×1
timeout ×1