当前位置: 首页 > news >正文

在Linux下如何实现禁止运行该程序多次?

1. 声明:本程序因为使用了cs模型,所以解决方法的时候存在server端的配合。如果你没有server端的话,可能该方法不适合你。

2. 问题描述,动态库文件libabcd.so,提供api接口实现程序。但是这个api中涉及到串口通信,msgq等,就要考虑让该动态库只运行一个实例。

3. 使用进程名的办法判断该库是否运行在本案例中不太恰当,因为可能有不同名的进程使用了这个库,那是无法通过进程名来限制的。

4. 使用文件锁(临时文件,空文件)的方式,实验失败,比如意外终止进程(ctrl+c)的情况下,文件锁似乎就没有成功解锁,导致想再次运行的时候就无法启动,总是提示已存在进程,实际是无法给对应的文件加锁而导致的,处理的方法则必须手动删除上锁文件,才能再次运行该程序。

可能有人会说要捕获该信号试试,但应该考虑可能调用该库的进程可能会捕获该信号,这个时候两个捕获函数肯定有一个会失效,所以这个方法不行。终止进程的信号无法被捕获(和忽略),这又是另外一个问题了。

5. 我的解决办法:因为现在已有客户端和服务端,他们之间的通信是msgq(消息队列)。我就利用了服务端来记录客户端的pid号处理的。

5.1 api提供一个init的函数,这个函数是必须调用的,调用的时候,会获取进程id(getpid),并且把该进程pid通过msgq发送给server端。

//检查进程是否正在运行,防止运行多个进程
//返回0,表示第一次启动API,否则为多次,则应该不允许启动
static int isProcessRunning()
{	
    //2022-08-09改为msgq通信确认进程是否存在,发送pid过去
    pid_t pid;
    int ret = 0;   //参数需要一个指针,返回函数返回值
    pid = getpid();  //获得自己的pid

	//查询是否存在api进程,让服务进程查询
	if(api_send_and_waitack(eAPI_CHECK_APIRUN_CMD,pid,&ret))  //发送的第二个参数表示pid,参数3用于返回结果,0表示没有启动API,1表示已经存在,-1表示出错
	{
		printf("error : isProcessRunning pid = %d\n",pid);
		return -1;
	}
	return ret;
  
}

5.2 server端(是守护进程),收到api的含有pid消息后,首先判断全局变量api_pid(初始值为0)记录的进程在系统中是否存在,不存在则用全局变量api_pid记录下刚刚收到的pid数据,并且给api返回0,表示允许刚刚的api进程启动。如果之前的pid还在系统中,则不记录收该pid,并且返回1,表示进程已经存在,不允许api再次启动。

		case eAPI_CHECK_APIRUN_CMD: //判断API库是否已经在运行,防止API库被多个进程使用
		//		printf("server : eAPI_CHECK_APIRUN_CMD pid = %d\n",pmsgbuf->param1);
				ret = check_api_running();  //看看是否存在
				if(ret == 0)
				{
		//			printf("server : eAPI_CHECK_APIRUN_CMD 111\n");
					api_pid = pmsgbuf->param1; //记录该pid号					
					msgbuf.param1 = 0;  //表示进程不存在
				}
				else
				{
		//			printf("server : eAPI_CHECK_APIRUN_CMD 222\n");
					msgbuf.param1 = 1;  //表示进程存在	
				}
				msgbuf.ret = 1; //表示有数据返回	
			break;

判断系统中是否存在某个pid的进程。 

static int check_api_running(void)
{
	char filename[256] = {0};

	if(api_pid < 1)   //不存在这样的进程
		return 0;

	snprintf(filename,sizeof filename,"/proc/%d/exe",api_pid);
	printf("server : check_api_running filename = %s\n",filename);

	if(access(filename,F_OK ) != -1)
	{
		printf("server : check_api_running access ok\n");
		return 1;   //进程已存在
	}
	printf("server : check_api_running access 0\n");
	return 0;  //进程不存在
}

 

5.3 api收到应答后,根据应答来决定是否继续运行进程,收到的值为0,表示可以继续启动,收到值为1,则退出,进程不再运行。

多次(可能小于100)测试(正常或异常终止api),暂时未发现问题。

 

可能大家还有其他思路,欢迎来多多指教交流。

相关文章:

  • HAIYPRH-PEG-DSPE,DSPE-PEG-HAIYPRH,磷脂-聚乙二醇-靶向肽HAIYPRH试剂供应
  • 发布自己的npm包注意事项
  • Vue的使用2
  • app毕业设计作品安卓毕业设计成品基于Uniapp+SSM实现的智能课堂管理
  • 神经网络试题答案,神经网络考试例题
  • 【论文分享】LibAFL: A Framework to Build Modular and Reusable Fuzzers
  • ESMM论文精读
  • 如何从容的打包上传图片对象--File,Blob,BASE64详解及转换方法
  • 广州市车联网先导区车联网先导区路侧感知技术规范
  • 【实用工具】frp实现内网穿透
  • PDF的图片怎么提取?这两种方法值得收藏
  • vue的函数式组件
  • 算法小讲堂之二叉排序树|二叉搜索树|BST
  • 软件性能测试报告怎么编写?哪些机构可以出具性能测试报告
  • 通过java爬取动态网页
  • 《深入 React 技术栈》
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【Amaple教程】5. 插件
  • 10个确保微服务与容器安全的最佳实践
  • Android系统模拟器绘制实现概述
  • ES6核心特性
  • ES6简单总结(搭配简单的讲解和小案例)
  • exports和module.exports
  • JavaScript设计模式与开发实践系列之策略模式
  • Java比较器对数组,集合排序
  • java取消线程实例
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • vuex 学习笔记 01
  • windows下如何用phpstorm同步测试服务器
  • Zepto.js源码学习之二
  • 给初学者:JavaScript 中数组操作注意点
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 解析带emoji和链接的聊天系统消息
  • 前端
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 区块链技术特点之去中心化特性
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​用户画像从0到100的构建思路
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (0)Nginx 功能特性
  • (39)STM32——FLASH闪存
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (三)docker:Dockerfile构建容器运行jar包
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (算法设计与分析)第一章算法概述-习题
  • (译)2019年前端性能优化清单 — 下篇
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .net mvc部分视图
  • .Net mvc总结