linux进程唯一实例,linux创建守护进程且进程中只有唯一实例

在编写服务进程的时候,经常有这样一个需求:保证服务进程只有一个实例在运行。

为实现这个简单的功能,有下面各种常见的实现方式:

1. 通过已知的进程名,来查询是否有同名的进程正在运行。

可以利用proc,也可以读取ps的输出等;

由于进程号可能被其他进程覆盖,所以必须确保改pid下的启动服务就是我们要的程序路径

找到某进程启动路径的方法是:

1.我们可以从ps命令中得到僵死进程的PID,如上例中23347

2.进入/proc目录下以该PID命名的目录中

3.输入ls -ail,结果中 exe链接对应的就是可执行文件的全路经详细信息

2. 利用pid文件,这也是linux各种服务常见的实现方式:

服务进程启动的时候,首先在指定目录下,一般为/var/run/,查找是否已经存在对应该进程的pid文件。

如果已经存在,表明有同样的进程在运行。但是也许该进程意外崩溃,所以需要进一步检查。读取该pid文件,获得pid。

然后再利用确定该pid的进程是否存在。如存在,是否为同名进程。

如果这个executable有多个进程在运行,那么我们得到的就是多个pid.这里的pid文件可能需要自己写入。

当然,我们还看到过lock file,一般都放在/var/lock/subsys/目录下面,如果一个deamon已经启动了,那么它的lock文件就应该存在了。

上面两种方式,是我以前常用的方法。后来,我更倾向于下面这种利用flock文件锁的方式。

闲话不说,见代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static int g_single_proc_inst_lock_fd = -1;

static void single_proc_inst_lockfile_cleanup(void)

{

if (g_single_proc_inst_lock_fd != -1) {

close(g_single_proc_inst_lock_fd);

g_single_proc_inst_lock_fd = -1;

}

}

B_BOOL is_single_proc_inst_running(const char *process_name)

{

char lock_file[128];

snprintf(lock_file, sizeof(lock_file), "/var/tmp/%s.lock", process_name);

g_single_proc_inst_lock_fd = open(lock_file, O_CREAT|O_RDWR, 0644);

if (-1 == g_single_proc_inst_lock_fd) {

fprintf(stderr, "Fail to open lock file(%s). Error: %s\n",

lock_file, strerror(errno));

return B_FALSE;

}

if (0 == flock(g_single_proc_inst_lock_fd, LOCK_EX | LOCK_NB)) {

atexit(single_proc_inst_lockfile_cleanup);

return B_TRUE;

}

close(g_single_proc_inst_lock_fd);

g_single_proc_inst_lock_fd = -1;

return B_FALSE;

}

注:这个代码由我自定义的类型,如B_BOOL。感兴趣的同学,可以自行更改。

is_single_proc_inst_running为关键函数,返回true,则表明只有一个进程实例在运行(本进程)。返回false则表明已有同名进程在运行了。

利用非阻塞的文件锁,对相应的文件进行上锁。成功获得文件锁的时候,就排斥了其它实例再次拿锁。在进程退出时,无论是正常退出还是意外崩溃的时候,Linux内核本身都会关闭该文件描述符。

当文件关闭时,文件锁都会被释放。这样新的服务进程可以再次启动。

但是我在写这个代码时,还是利用atexit,实现了对该文件描述符的关闭。即使加了这个不必要的实现,这份代码仍然比最早提出的两种方式要简单的多。 这份代码没有考虑多线程竞争,因为没有必要。一般来说,检测进程唯一实例应该是在进程刚刚启动的时候。那时,应该只有一个线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值