#!/bin/sh
xmessage 'hello this is the first xmessage' &
last=$(ps -a | grep '[ ]xmessage$' | awk '{print $1}')
sleep 1
if test $(($(date +%s) % 2)) -eq 0
then
kill $last
fi
sleep 1
if ! ps -p $last >/dev/null
then
xmessage 'Hi, this is the second xmessage. Visible only if the first is close!' &
fi
可以测试(命名)管道的可写性,并通过适当的编程测试正在运行的程序实例的存在。
假设我们保留一个文件名
/tmp/fifo-myapp
作为 FIFO 文件的名称(它应该为每个不同的应用程序定制;它通常驻留在一些特定于应用程序的文件夹并指定为绝对路径):文件1:
test-wr-fifo
当 fifo 未打开且已达到指定超时时,此程序将以不成功状态退出。
文件2:
single-inst-prog
这是我们只需要 1 个实例的程序。
调用
single-inst-prog
:此方法有效,因为打开 FIFO 的一端会阻塞(当 O_NONBLOCK 清零时),直到另一端也打开;此方法也有效,因为我们没有从 FIFO 读取或写入任何数据,因此永远不会发出 EOF 条件和 SIGPIPE 信号。
我总是对锁文件的竞争条件保持警惕,所以我使用一个特定的命名文件,并使用它,
mv
因为它是原子的。通常,该过程使用永久文件名,例如
/tmp/locks/myProcess.lock
. 任何希望获得锁的进程都会尝试将名称更改为/tmp/locks/myProcess.lock.myPID
(mv(1)
用于 shell 和rename(2)
C)。然后它可以检查它的私有名称现在是否存在。如果不是,它会根据需要循环/睡眠。稍加注意,进程可以将日志附加到锁定文件中:何时尝试锁定,何时成功,何时释放。
显然,它必须记住第一次尝试的时间,因为它只能在成功后记录。它还可以监视过度延迟并发出警报以进行调查(可能另一个进程复制失败,并且没有 onExit 来释放锁)。
这是一个带有 xmessage 的示例。不确定它是否适合您,但您可以尝试一下。