如何让程序真正地在后台运行?,
如何让程序真正地在后台运行?,
如何实现一个守护进程?如何让程序在后台运行?这是后台开发面试常问的一道题,那么守护进程到底是什么?又该如何实现?
守护进程
守护进程通常生存期长,很多是在系统启动时启动,系统退出时才关闭。它们的特点通常没有控制终端,后台运行。有人可能会会心一笑,后台运行程序,我知道呀。还有两种方式呢
看,多么简单。但是运行之后,你试着关闭当前终端,你会发现程序会停止运行,因为一旦关闭终端,程序会收到一个信号SIGHUP,而收到该信号默认的动作就是程序退出。没关系啊,我还有招:
我使用nohup命令总可以了吧?挺好的,nohup会忽略SIGHUP命令,并有了&的加持,即便终端关了,也能继续执行。但它的终端输出还会记录默认还在nohup.out文件中,同时,如果将huponexit关闭,它同样难逃命运:
一旦终端退出(ctrl+D)后,nohup也救不了。下面要介绍的守护进程一一种完全脱离终端,有着自己的会话。
如果你在你的Linux系统中执行下面的命令:
就会发现一些进程的tty列是?,当然这并不是说明它们是守护进程,而那些用[]括起来的,是内核守护进程想象一下,如果没有任何人登录的服务器上面的运行程序,难道每次执行的时候都要使用nuhup+&?况且,一旦系统的huponexit选项是打开的,这种方式仍然无法避免终端关闭程序就退出的命运!那么就需要实现用户守护进程了,或者说daemon化。
如何实现
其实现过程基本遵循以下原则:
- 调用umask设置文件模式,通常设置为0。为了便于后续创建文件,不使用继承而来的父进程的设置,需要设置新的权限掩码。
- 调用fork,创建子进程,并且父进程退出
- 调用setdid创建新的会话(一个或多个进程组的集合),由于当前进程不是一个进程组的组长,因此会创建一个新的会话,却成为组长进程,同时没有控制终端。
- 将当前工作目录切换为根目录。同样的,其工作目录可能是从父进程继承而来的,可以自己另立山头。
- 关闭不需要的文件描述符。同样的,可能从父进程继承了一些打开的文件描述符,而这些描述符可能再也不需要,因此可以关闭。
- 重定向标准输出,标准输入和标准错误到/dev/null
- 实际上,从上面的描述可以发现,这些规则都有几乎相同的目标,那就是不想成为富二代,摆脱父亲的控制。
-
- 重新设置权限掩码,避免受父进程影响
- 创建新的会话,脱离终端
- 使用新的工作目录
- 关闭不需要的文件描述符
- 关闭标准输入,标准输出和标准错误
具体实现
参考代码如下:
编译运行,你就会发现,它已经可以欢脱地运行啦。
实际实现
实际上,已经有一个接口可以帮我们做这些事情:
即daemon函数,它有两个参数
- nochdir 为0时,表示修改其根目录为/,否则不变
- noclose,为0时,表示将标准输入,标准输出,标准错误重定向到/dev/null。
简单例子:
总结
以上就进程后台运行以及是守护进程实现的介绍,关键点有
- 创建子进程,父进程退出
- 创建新的会话,脱离终端
附上daemon的源码:
我是一名java程序员,更多的java经验技术分析可以来我的编程技术讨论扣峮1080621881 ,不过你是零基础还是刚入门,你都可以来,有很多适合刚入门的伙伴学习的资料分析详解。
相关文章
- 暂无相关文章
用户点评