在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),暂时未发现问题。

 

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大智兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值