扫盲:守护进程、后台进程、守护线程和用户线程

  1. 1. 线程和进程
  2. 2. 守护进程和后台程序
    1. 2.1. nohup
  3. 3. 前后台程序切换
    1. 3.1. 前台程序到后台运行
    2. 3.2. 后台程序到前台运行
  4. 4. 用户线程和守护线程

线程和进程

进程是对运行时程序的封装,是资源分配的最小单位,进程实现了操作系统的并发,进程在执行过程中拥有独立的内存单元。

线程是进程的子任务,是 CPU 调度的最小单位,线程实现了进程内部的并发,多个线程共享进程的内存。

守护进程和后台程序

守护进程(Daemon)是在后台运行的一种特殊进程,它脱离于终端,不会被任何终端所产生的信号打断,它在执行过程中所产生信息也不在任何终端上显示,守护进程周期性地执行某种任务或等待处理某些发生的事件。

Linux 的大多数服务器就是用守护进程实现的,例如:Internet 服务器 inetd 和 Web 服务器 httpd。

后台程序是在后台运行的程序,可以通过 Command & 来运行,后台程序并未完全脱离终端,终端未关闭前还是会往终端输出结果。如果终端关闭,那么程序也会被关闭。

nohup

nohup Command用于不挂断地运行命令,即使终端关闭了也会一直运行,我们可以通过运行 nohup Command & 来达到守护进程的部分效果。

例如,我们经常通过nohup java -jar <jarName>.jar & 命令来运行 Spring Boot 项目

默认情况下,所有输出都被重定向到当前目录一个名为 nohup.out 的文件中,nohup.out 相当于日志,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中,如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。

前后台程序切换

前台程序到后台运行

运行如下命令即可切换前台程序到后台运行:

1
2
ctrl + z  # 将一个正在前台运行的程序放到后台,并处于暂停状态
bg %进程序号 # 继续运行一个后台暂停的程序,如果只有一个程序,可省略参数

示例如下:

1
2
3
zsh: suspended  java -jar target/novel-front-3.6.2.jar
xiongxiaoyang@xiongxiangdeAir novel-front % bg %1
[1] + continued java -jar target/novel-front-3.6.2.jar

后台程序到前台运行

运行如下命令即可切换后台程序到前台运行:

1
fg %进程序号 # 如果只有一个程序,可省略参数

示例如下:

1
2
xiongxiaoyang@xiongxiangdeAir novel-front % fg %1
[1] + running java -jar target/novel-front-3.6.2.jar

用户线程和守护线程

在 Java 中,线程分为用户线程守护线程,守护线程是用来为用户线程服务的,当一个程序中的所有用户线程都结束之后,无论守护线程是否在工作都会跟随用户线程一起结束,垃圾回收机制就是典型的守护线程。

守护线程从业务逻辑层面来看权重比较低,但对于线程调度器来说无论是守护线程还是用户线程,在优先级相同的情况下被执行的概率都是相同的。

举个例子,当 main 线程退出后,里面的子线程还在运行,如果我们通过Thread::setDaemon(true)将子线程设置为守护线程后,子线程会随着 main 线程的结束而退出。