Monday, May 24, 2010

xxx.pid文件与lock file

linux下, xxx.pid这类文件还是很常见的, 特别是在/var/run目录下, APUE一书都是推介在这里创建pid文件。
pid文件到底有什么作用呢? 用法是如何的呢?种种疑问让我产生了dig的冲动。

先看看实现生活中碰到的:

1. init.d脚本使用到pid文件

/etc/init.d目录下存放了众多daemon程序的控制脚本,这类脚本一般有几个参数:
  1. start
  2. retstart
  3. stop
  4. 强大的专业服务端还有gracestop之类的参数
这类脚本的这些参数功能的实现是使用到了linux的signal机制, 无疑需要daemon进程的pid

2. lock

lock主要是协调, 操作atomic时使用的一种方式。
举个实际中的例子:
系统需要一个定时任务, 要求每分钟对系统N多状态收集(如硬盘,CPU, 网络等等), 收集过程中不断有日志产生。

这个例子会有两个问题:
  1. 运行间隔为每分钟, 可能会定时任务某次运行时长长于1分钟。
  2. 如果出现1的情况会对日志产生影响
lock主要是用于证实有进程在处理。

linux系统本身有锁的机制, 如flock和fcntl函数。 这种锁称为file lock, 文件锁
linux下的文件锁可以对一个文件的一个区域进行锁定。

现在, 本笔记不想扯上这种强大功能, 只是谈论上面举的例子: 怎么让进程得到一个結果:能否处理

完成这需求, 只需要一个标志, 这个标志需要进程在得到时是atomic性的。

可以通过两种方法得这种标志:
  1. 指定文件已经存在, 表示有进程在处理. 这种方式称为lock file
  2. 使用系统本身的file lock机制, 如果open的file descriptor有锁, 表示有进程在处理

使用linux的flock函数得到file lock, 这里有一个python的例子:
http://svn.lvscar.info/jessinio_repos/flock_example.py
  * 帐号与密码都是svn

lock file 和 file lock 的区别

lock file是利用系统本身的open, link, stat这样的函数, 实现文件创建的atomic性. 成功被创建的文件作为atomic的标志

file lock是利用系统本身的fcntl或者flock函数对某一的文件进行锁定, 将能否成功锁定文件作为atomic的标志

无论是lock file 还是 file lock都是需要文件这一角色的. 但是这一文件起的作用不同.

本文主要是想扯lock file与xxx.pid文件的关系. 不想扯file locklock file

仅仅需要可以标志行为的atomic性的话, lock file是最好的方法:
1. NFS上可以使用(flock函数在旧版本的NFS上不起作用)
2. shell脚本可用. 因为是shell脚本是CLI, 时刻都是新的进程在处理, 不方便使用flock(这样需要一个daemon在保持file lock的存在
 * 关于 lock file可以移步: http://en.wikipedia.org/wiki/File_locking#Lock_files

使用lock file需要解决的问题

当使用lock file作为atomic的标志时, 有一种情况是需要解决的: 持锁者是否还存在, 例如:

当一个进程成功创建了lock file后, 在不明异常的情况终止了, 后面的进程怎么判断刚才被创建的lock file是被进程使用的? ( 使用file lock就没有这种问题, 得到锁的进程终止后锁会被释放, 新的进程可以得到)

具体处理方式可以参考liblockfile的原代码:
 * http://liblockfile.sourcearchive.com/documentation/1.06.1/lockfile_8c-source.html

在它的lockfile_check函数里, 使用到了kill函数. 这个kill函数需要的pid就是xxx.pid文件的pid

因此:

xxx.pid有两种作用:
1. 方便daemon被控制(通过signal)
2. 可以用于实现lock file

利用了1不一定利用2, 但是作用了2一定需要利用1

另外

除了利用kill给指定的pid发signal的方式去判断某进程是否存在的方式后, 还可以使用如下URL提到的方法:
http://stackoverflow.com/questions/2735926/how-to-capture-pid-of-a-linux-daemon-run-from-init-d

利用/proc/NamePID/exe得到的字符串是否为先前在进行的进程名. 这种方法需要知道进程的名称.

疑问

是否会出现pid号的进程存在, 但不是自己期望的进程呢?
查阅了APUE也没有明确, 只知道是有一定的算法去reuse 进程号的.

在这方面, 还是flock方便, 不过此函数不是所有地方都可以使用的, 纠结`~~





No comments:

Post a Comment

Note: Only a member of this blog may post a comment.