java 如何让程序一直运行的程序_如何让程序真正地在后台运行?

本文详细介绍了如何使Java程序作为守护进程在后台持续运行,包括理解守护进程特性、使用nohup命令、实现daemon化的过程,以及提供具体的代码示例。通过创建子进程、设置新的会话、关闭不必要的文件描述符等方式,确保程序不受终端影响,实现长期运行。

正版现货核心(原书第2版)基础教程

106.5元

包邮

(需用券)

去购买 >

602e5b4ba6cdbae0e633164e15fe4f58.png

如何实现一个守护进程?如何让程序在后台运行?这是后台开发面试常问的一道题,那么守护进程到底是什么?又该如何实现?

守护进程

守护进程通常生存期长,很多是在系统启动时启动,系统退出时才关闭。它们的特点通常没有控制终端,后台运行。有人可能会会心一笑,后台运行程序,我知道呀。还有两种方式呢

e5db197bd322fbd78962b35091b65264.png

看,多么简单。但是运行之后,你试着关闭当前终端,你会发现程序会停止运行,因为一旦关闭终端,程序会收到一个信号SIGHUP,而收到该信号默认的动作就是程序退出。没关系啊,我还有招:

41210606c6e893aac01f07dbe4361639.png

我使用nohup命令总可以了吧?挺好的,nohup会忽略SIGHUP命令,并有了&的加持,即便终端关了,也能继续执行。但它的终端输出还会记录默认还在nohup.out文件中,同时,如果将huponexit关闭,它同样难逃命运:

07277e8e1d0a6b86cf64dbd1263d3004.png

一旦终端退出(ctrl+D)后,nohup也救不了。下面要介绍的守护进程一一种完全脱离终端,有着自己的会话。

如果你在你的Linux系统中执行下面的命令:

2df93a09e8d9390dc89dc4ef63881c2e.png

就会发现一些进程的tty列是?,当然这并不是说明它们是守护进程,而那些用[]括起来的,是内核守护进程想象一下,如果没有任何人登录的服务器上面的运行程序,难道每次执行的时候都要使用nuhup+&?况且,一旦系统的huponexit选项是打开的,这种方式仍然无法避免终端关闭程序就退出的命运!那么就需要实现用户守护进程了,或者说daemon化。

如何实现

其实现过程基本遵循以下原则:

调用umask设置文件模式,通常设置为0。为了便于后续创建文件,不使用继承而来的父进程的设置,需要设置新的权限掩码。

调用fork,创建子进程,并且父进程退出

调用setdid创建新的会话(一个或多个进程组的集合),由于当前进程不是一个进程组的组长,因此会创建一个新的会话,却成为组长进程,同时没有控制终端。

将当前工作目录切换为根目录。同样的,其工作目录可能是从父进程继承而来的,可以自己另立山头。

关闭不需要的文件描述符。同样的,可能从父进程继承了一些打开的文件描述符,而这些描述符可能再也不需要,因此可以关闭。

重定向标准输出,标准输入和标准错误到/dev/null

实际上,从上面的描述可以发现,这些规则都有几乎相同的目标,那就是不想成为富二代,摆脱父亲的控制。

重新设置权限掩码,避免受父进程影响

创建新的会话,脱离终端

使用新的工作目录

关闭不需要的文件描述符

关闭标准输入,标准输出和标准错误

所以通过这些也可以明白,有些规则并不是完全强制的,可根据实际程序的情况进行设置,不过按照常规做法是一个比较好的选择。

具体实现

参考代码如下:

304f0a934ad80f172c1773286d2cce88.png

3130b5f1338991a5b0c3b9e9893d7606.png

编译运行,你就会发现,它已经可以欢脱地运行啦。

实际实现

实际上,已经有一个接口可以帮我们做这些事情:

3380807002bf105a0eb63fc4c88b28b9.png

即daemon函数,它有两个参数

nochdir 为0时,表示修改其根目录为/,否则不变

noclose,为0时,表示将标准输入,标准输出,标准错误重定向到/dev/null。

简单例子:

56bb7b71b2c8a46292055edd0076c083.png

总结

以上就进程后台运行以及是守护进程实现的介绍,关键点有

创建子进程,父进程退出

创建新的会话,脱离终端

附上daemon的源码:

5c9ec1420729599186b682e71d8c33f5.png

我是一名java程序员,更多的java经验技术分析可以来我的编程技术讨论扣峮1080621881 ,不过你是零基础还是刚入门,你都可以来,有很多适合刚入门的伙伴学习的资料分析详解。

java 11官方入门(第8版)教材

79.84元

包邮

(需用券)

去购买 >

f0f3f55624fb396b1764d42d6df88864.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值