关于Linux 系统程序(进程)自动升级的方法

        项目有一个CS架构的客户端程序需要远程升级,client从server下载升级包,升级包最好做一个校验,避免文件出错导致升级失败。一般用md5校验,下载的升级包一般包含成一个文本文件和一个升级文件,文本文件中记录升级文件的md5值。client端接收到升级包后计算升级包里面的升级文件的MD5值,然后与文本文件里面的MD5比较,MD5值不相等,说明文件错误,不能用来升级。

        升级包下载好后,关键是如何加载,升级是要下载当前的client进程,然后加载新的client进程。原来我们是在client进程里面调用一个shell脚本,在这个脚本里面执行卸载老进程,加载新进程的工作。该方法功能上可用,但会有一个资源泄漏的隐患。

        Client调用shell脚本是通过fork实现的,本质上shell是client进程的子进程,然后shell里面加载的client进程又是shell的子进程。我们知道子进程是复制父进程的资源的,比如client进程打开了一个文件句柄,这个文件句柄最终会传递到新加载的client进程中,新加载的client里面功能执行后,又会重新打开一个文件句柄。反复多次升级后 client进程占用的句柄会越积越多。

        为了避免上述情况,需要用其它的进程加载新下载的Client。可以设计一个专门的deamon守护进程,负责加载Client。也可以用系统的crond,Client进程下载后自己退出,然后通过crond周期检查,发现client进程不走时,加载Client.

       另外句柄继承也可以通过close-on-exec机制解决,在创建socket时增加SOCK_CLOEXEC,同样在文件的句柄Open打开时增加O_CLOEXEC

       SOCKET ss = ::socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);

      int fd = open(“foo.txt”,O_RDONLY | O_CLOEXEC);

     或者通过fcntl设置

      int flags = fcntl(fd, F_GETFD);  
      flags |= FD_CLOEXEC;  
      fcntl(fd, F_SETFD, flags); 

 

     

 

 

       

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值