Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何确保应用程序运行的唯一性

如何确保应用程序运行的唯一性

作者头像
用户1278550
发布于 2018-08-09 02:47:51
发布于 2018-08-09 02:47:51
1.4K0
举报
文章被收录于专栏:idbaidba

一 简介 相信大家在开发脚本或者写程序的时候 ,大多会遇到如何判断已经有程序在运行的情况。比如设计备份binlog ,由于某个实例产生的binlog 数量大于备份的速度,在下一个时间点,会启动一个新的进程对binlog进行备份。那我们要怎么解决呢,本文分别从 shell和python的角度提出我的解决方法,同时也推荐《 Ensure a single instance of an application in Linux》[1],这里有比较详细的讨论。

二 shell 脚本的解决方法 利用mkdir 的特性 创建已经存在的文件目录则会失败。程序第一次运行的时候可以创建一个 /tmp/lock文件夹,标示当前已经运行一个程序,当启动第二个程序时,mkdir /tmp/lock 便会失败。

  1. #!/bin/bash
  2. mkdir /tmp/lock
  3. if [ $? -ne 0 ];then
  4. echo "there is tr script running .. "
  5. exit 1
  6. fi
  7. trap "rm -fr /tmp/lock " SIGINT SIGTERM
  8. sleep 50
  9. if [ -d /tmp/lock ];then
  10. rm -fr /tmp/lock
  11. echo "rm -fr /tmp/lock"
  12. fi

注意 linux中的trap命令是防止脚本异常终止 :被kill (不是kill -9) ,crtl+c 中断 比较详细的资料 《Linux命令之trap - 在脚本中处理信号》[2] 三 python 脚本的解决方法 网上搜索python 锁定文件的时候,都会提示 fcntl 模块。Python的文件锁是由fcntl这个库实现的,它实际上为 Unix上的ioctl,flock和fcntl 函数提供了一个接口。 fcntl模块的函数flock(file_handle, operation) 其中 file_handle 表示文件描述符,operation 指要进行的锁操作,有如下几种: fcntl.LOCK_UN 解锁:删除floc()函数创建的锁 fcntl.LOCK_EX 排他锁:除加锁进程外其他进程没有对已加锁文件读写访问权限。 fcntl.LOCK_SH 共享锁:所有进程没有写访问权限,即使是加锁进程也没有。所有进程有读访问权限。 fcntl.LOCK_NB 非阻塞锁: 此参数意味着函数不能获得文件锁就立即返回,否则,如果使用LOCK_EX/LOCK_SH请求加锁不成功,则当前进程会等待获得文件锁。使用LOCK_NB可以在获得这个排他锁的情况下不阻塞该进程,LOCK_NB 也可以同LOCK_SH或LOCK_NB进行按位或(|)运算操作,比如fcnt.flock(file_handle,fcntl.LOCK_EX|fcntl.LOCK_NB),此时系统便不会阻塞当前的进程。 注意: 1. 对于文件的f.close() 操作会使文件锁失效; 2. 主进程结束后文件锁失效; 3. flock()的LOCK_EX是"劝告锁",系统内核不会强制检查锁的状态,需要在代码中进行文件操作的地方显式检查才能生效。 测试脚本 脚本中使用is_running 函数对文件加锁,time.sleep(10) 模拟长时间执行的程序,第一次运行lock.py 成功加锁,在程序运行期间 再次运行lock.py ,获取锁时会失败,并且及时退出程序。

  1. #!/usr/bin/python2.6
  2. #coding:utf8
  3. import time
  4. import fcntl
  5. import sys
  6. def is_running(file):
  7. lock_file=open(file,"w")
  8. try:
  9. fcntl.lockf(lock_file,fcntl.LOCK_EX|fcntl.LOCK_NB)
  10. print "给文件加锁 ,请等待10s..."
  11. except :
  12. print '文件加锁,无法执行,请稍后运行。'
  13. return None
  14. return lock_file
  15. if __name__ == "__main__":
  16. lockfile="/tmp/rsync_is_running"
  17. a=is_running(lockfile)
  18. if a is None :
  19. print "lock file failed , rsync is running .quit ..."
  20. sys.exit(0)
  21. else :
  22. print "lock file successed !!! "
  23. time.sleep(10)

测试例子: 会话一

会话二

其实还可以有很多其他的方式 比如 最容易想到的是根据 当前进程的 application_name.pid 或者

ps application_name | wc -l 来判断,不过使用ps 命令时,遇到和系统其他命令关键字一样的时候 ,就会不准。http://stackoverflow.com/ 中比较推荐使用pid ,各位读者朋友也可以提出自己的见解。欢迎讨论。

四 参考文章

[1] https://stackoverflow.com/questions/220525/ensure-a-single-instance-of-an-application-in-linux

[2] http://codingstandards.iteye.com/blog/836588

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
flock分析与文件权限问题
贴一个试验代码, 子进程直接获取锁, 若获取不到则输出错误; 父进程睡3秒后退出.
平凡的学生族
2021/03/04
9170
linux C语言实现文件锁
flock函数说明 flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。 表头文件 #include<sys/file.h> 定义函数 int flock(int fd,int operation); 参数 operation有下列四种情况: LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。 LOCK_EX 建立互斥锁定。一个文件同时只有一
一灰灰blog
2018/02/06
8.7K0
Linux 中 fcntl()、lockf、flock 的区别
这三个函数的作用都是给文件加锁,那它们有什么区别呢?首先flock和fcntl是系统调用,而lockf是库函数。lockf实际上是fcntl的封装,所以lockf和fcntl的底层实现是一样的,对文件加锁的效果也是一样的。后面分析不同点时大多数情况是将fcntl和lockf放在一起的。下面首先看每个函数的使用,从使用的方式和效果来看各个函数的区别。 1. flock 函数原型 int flock(int fd, int operation); // Apply or remove an advisory
小小科
2018/05/04
6.3K1
Linux 中 fcntl()、lockf、flock 的区别
python的文件锁使用
python的文件锁目前使用的是fcntl这个库,它实际上为 Unix上的ioctl,flock和fcntl 函数提供了一个接口。
py3study
2020/01/07
5.8K0
嵌入式Linux:文件锁
Linux 文件锁是一种用于管理多进程或多线程环境中资源访问的机制,确保只有一个进程或线程在特定时间内对文件进行操作,从而避免数据不一致的情况。
不脱发的程序猿
2025/04/01
1150
嵌入式Linux:文件锁
并发锁(二):共享锁和独占锁
共享锁用于某个文件不会被写,或者不会被更新(也就是只读)的情况,加了共享锁的文件,只能再加共享锁,而不能加独占锁
仙士可
2019/12/18
1.7K0
PHP基于文件锁解决多进程同时读写一个文件问题示例
/【一个开发人员,能懂服务器量好,反之一个服务器维护人员,也应该懂开发】/ 本文实例讲述了PHP基于文件锁解决多进程同时读写一个文件问题。分享给大家供大家参考,具体如下: 首先PHP是支持进程的而不支持多线程(这个先搞清楚了),如果是对于文件操作,其实你只需要给文件加锁就能解决,不需要其它操作,PHP的flock已经帮你搞定了。 用flock在写文件前先锁上,等写完后解锁,这样就实现了多线程同时读写一个文件避免冲突。大概就是下面这个流程
用户2323866
2021/07/06
5110
golang下文件锁的使用[通俗易懂]
题目是golang下文件锁的使用,但本文的目的其实是通过golang下的文件锁的使用方法,来一窥文件锁背后的机制。
全栈程序员站长
2022/09/13
2.6K0
Linux中如何对文件加锁
在Linux中,文件加锁是通过使用文件锁(File Locks)来实现的。文件锁主要有两种类型:共享锁(Shared Lock)和排他锁(Exclusive Lock)。这些锁用于控制对文件的并发访问,以防止多个进程同时对同一文件进行读或写操作,从而保护文件的一致性。
Linux兵工厂
2024/02/27
6420
Linux中如何对文件加锁
脚本并发问题:脚本并发执行时出现竞争条件,导致问题
在 Python 中,可以使用 threading.Semaphore 或 multiprocessing.Semaphore 实现信号量:
是山河呀
2025/02/07
1250
PHP 高级编程之多线程
PHP 高级编程之多线程 http://netkiller.github.io/journal/php.thread.html ---- 目录 1. 多线程环境安装 1.1. PHP 5.5.9 1.2. 安装 pthreads 扩展 2. Thread 3. Worker 与 Stackable 4. 互斥锁 4.1. 多线程与共享内存 5. 线程同步 6. 线程池 6.1. 线程池 6.2. 动态队列线程池 6.3. pthreads Pool类 7. 多线程文件安全读写(文件锁) 8. 多线程与数据连
netkiller old
2018/03/05
2.8K0
PHP文件锁
食堂管理员A有点偷懒,不想等那么久,于是就告诉大家,中午都可以来食堂吃饭,但是要跑快点才行,只有一个座位,第一个到的人就可以在食堂吃饭,然后就会锁门,其他人看到门锁上了就哪来的回哪去吧,这就是非阻塞型文件锁;
全栈程序员站长
2022/09/13
2.2K0
PHP文件锁
Linux 中的文件锁定命令:flock、fcntl、lockfile、flockfile
在 Linux 系统中,文件锁定是一种对文件进行保护的方法,可以防止多个进程同时访问同一个文件,从而导致数据损坏或者冲突。文件锁定命令是一组用于在 Linux 系统中实现文件锁定操作的命令,它们可以用于对文件进行加锁或解锁,控制文件的访问权限,保证系统的稳定性和安全性。在本文中,我们将详细介绍 Linux 中的文件锁定命令,包括锁定的类型、命令的使用方法、常见问题及解决方法等内容。
网络技术联盟站
2023/05/08
4K0
Linux 中的文件锁定命令:flock、fcntl、lockfile、flockfile
PHP文件锁封装备份代码
高久峰
2023/06/03
3510
Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏
1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足。 1.1 相关函数  #include <pthread.h>  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t*cond_attr);  int pthread_cond_signal(pthread_cond_t *cond);  int
三丰SanFeng
2018/01/16
3K0
flock()函数使用示例
注:在进程退后,会自动解锁。 #include <stdio.h> #include <stdlib.h> #include <sys/file.h> // 提供flock()函数,从#include可以看出,它是一个系统调用,而不是一个库函数 #include <unistd.h> // 编译方法: // 假设文件名为x.cpp,则为g++ -g -o x x.cpp // 需要带一个命令行参数argv[1], // 必
一见
2018/08/10
1.2K0
从并发处理谈PHP进程间通信(一)外部介质
枕边书
2018/01/04
1.3K0
怎么正经的实现shell脚本单例运行?
一个非常简单的思路就是,新的脚本被执行时,先检测当前脚本是否有其他实例正在运行,如果有则直接退出。
编程珠玑
2020/05/27
2.3K0
聊聊Yii2和ThinkPHP5的文件缓存
Yii2和ThinkPHP5缓存操作提供的公共方法对比 Yii2缓存提供的方法 get 获取缓存 set 设置缓存数据 exists 判断缓存是否存在 mset multiSet 方法别名,批量设置缓存 mget multiGet 方法别名,批量获取缓存 add 添加缓存返回true,存在则不做操作 madd 批量添加多个,返回成功插入数组 delete 删除缓存 flush 清空缓存所有数据 offsetExists ,exists别名 offsetGet ,get别名 offsetSet,se
写PHP的老王
2019/08/12
1.3K0
用 abstract unix socket 实现进程单实例运行
http://stackoverflow.com/questions/2964391/preventing-multiple-process-instances-on-linux
byronhe
2021/06/25
1.3K0
相关推荐
flock分析与文件权限问题
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档