美文网首页
进程安全退出

进程安全退出

作者: JinMoon | 来源:发表于2018-07-25 19:54 被阅读5次
正常关闭
  • 系统关机:操作系统会自动关闭进程?
异常关闭:
  • kill -9
  • Runtime.halt()
  • 断电
  • 系统crash
kill -9 和 kill -15 有什么区别?

kill -15 pid的作用是向进程号为pid的进程发送SIGTERM(kill默认发送的信号ID就是15,所以可以简写成kill pid),该信号是一个结束进程的信号且可以被应用程序捕获,若应用程序没有捕获并响应该信号的逻辑代码,则该信号的默认动作是kill掉进程(等价于-9)。kill pid是终止指定进程的推荐做法。

kill -9 pid则是向进程号为pid的进程发送SIGKILL(该信号的编号为9),SIGKILL既不能被应用程序捕获,也不能被阻塞或忽略,其动作是立即结束指定进程。通俗地说,应用程序根本无法“感知”SIGKILL信号,它在完全无准备的情况下,就被收到SIGKILL信号的操作系统给干掉了,可以认为对于被kill的进程来说,kill -9 pid模拟了一次系统宕机(断电)。

显然,在这种“暴力”情况下,应用程序完全没有释放当前占用资源的机会,一般不推荐作为进程终止的方式。事实上,SIGKILL信号是直接发给init进程的,它收到该信号后,负责终止pid指定的进程。通常在某些异常情况下(如进程已经hang死,无法响应正常信号)会使用kill -9来结束进程。

若通过kill结束的进程是一个创建过子进程的父进程,则其子进程就会成为孤儿进程(Orphan Process),这种情况下,子进程的退出状态就不能再被应用进程捕获(因为作为父进程的应用程序已经不存在了),而是交由init进程(1号进程)代为捕获和清理,通常也不会对整个linux系统产生什么不利影响。

应用程序如何安全、优雅地退出?

在Linux上很多应用通常会通过kill -9 pid的方式强制将进程杀掉,这种方式简单高效,因此很多应用的停止脚本经常会选择使用kill -9 pid的方式。但是,Server程序经常会长时间运行,在运行过程中,可能申请了很多系统资源,也可能保存了很多状态,而 kill -9 pid相当于系统宕机/系统断电,可能会带来一些副作用:

  • 缓存中的数据尚未持久化到磁盘中,导致数据丢失;
  • 分布式集群中数据不一致;
  • 网络连接、共享内存、消息队列等得不到及时释放;
  • 正在进行文件的write操作,没有更新完成,突然退出,导致文件损坏;
  • 线程池的任务队列中尚有接收到的任务还没来得及处理,导致任务丢失;
  • 数据库操作已经完成,例如账户余额更新,准备返回应答消息给客户端时,消息尚在通信线程的发送队列中排队等待发送,进程强制退出导致应答消息没有返回给客户端,客户端发起超时重试,会带来重复更新问题;
  • 其它问题等…

一般需要在进程关闭时处理一下“善后”工作,比如

  • 关闭 socket 链接
  • 清理临时文件
  • 发送消息通知给订阅方,告知自己下线
  • 将自己将要被销毁的消息通知给子进程
  • 各种资源的释放(共享内存、消息队列、互斥锁等)

可以通过捕获SIGTERM信号来实现安全、优雅地退出,如果在某次实际操作中发现:kill -15 pid 无法关闭应用,则可以考虑使用内核级别的 kill -9 pid ,但请事后务必排查出是什么原因导致 kill -15 pid 无法关闭。

实现步骤

具体来讲,通常只需要两步动作:

  • 注册SIGTERM信号的处理函数并在处理函数中做一些进程退出的准备。信号处理函数的注册可以通过signal()或sigaction()来实现,其中,推荐使用后者来实现信号响应函数的设置。信号处理函数的逻辑越简单越好,通常的做法是在该函数中设置一个bool型的flag变量以表明进程收到了SIGTERM信号,准备退出。
  • 在主进程的main()中,通过类似于while(!bQuit)的逻辑来检测那个flag变量,一旦bQuit在signal handler function中被置为true,则主进程退出while()循环,接下来就是一些释放资源或dump进程当前状态或记录日志的动作,完成这些后,主进程退出。

相关文章

  • 进程安全退出

    正常关闭 系统关机:操作系统会自动关闭进程? 异常关闭: kill -9 Runtime.halt() 断电 系统...

  • Swoole 进程模块高级

    进程相关高级操作 主进程退出子进程干完活后也退出子进程异常退出主进程自动重启子进程

  • 父进程退出时如何确保子进程退出

    前言 子进程退出的时候,父进程能够收到子进程退出的信号,便于管理,但是有时候又需要在父进程退出的时候,子进程也退出...

  • 进程

    孤儿进程:父进程退出的子进程。会被init进程(进程号为1)收养,并负责其状态收集。不会产生危害。僵尸进程:退出后...

  • 进程之其他进程

    僵尸进程 定义 子进程先于父进程退出,父进程没有对子进程的退出做出相应的处理,此时子进程就会变成僵尸进程 影响 进...

  • TODO:Golang Linux进程退出说明

    TODO:Golang Linux进程退出说明 Golang使用os.Exit(code)进程退出导致当前程序退出...

  • python学习笔记-多任务

    进程 主进程会等待子进程执行完成以后程序在退出 解决办法:主进程退出子进程销毁1、让子进程设置成为守护主进程,主进...

  • 僵尸进程的产生和防范

    僵尸进程 僵尸进程的产生 fork产生的父进程和子进程有退出的先后顺序,如果子进程在父进程前退出就会产生,而父进程...

  • Android应用启动、退出分析

    §AMS和应用进程§应用启动流程§应用退出流程§启动、退出消息 AMS和应用进程 应用进程 <- 系统管理 <- ...

  • linux-08-进程管理2

    今天:进程结束 -fork() /exit退出进程/wait()父进程等待子进程/vfork()Unix/Linu...

网友评论

      本文标题:进程安全退出

      本文链接:https://www.haomeiwen.com/subject/fnspmftx.html