进程间的关系
前台进程:
当在终端运行一个命令时,默认情况下,该命令会在前台运行。这意味着你必须等待命令完成才能继续在终端中输入其他命令。
后台进程
当一个进程在后台运行时,它不会占用终端的输入。启动一个后台进程后,可以在同一个终端窗口中执行其他命令,而不必等待后台进程完成。为了在后台启动进程,通常在命令后添加 &。
例如: command &
前台和后台进程区别
-
前台进程:必须等待终端的命令完成才能继续在终端中输入其他命令
-
后台进程:不占用终端,可以在同一个终端中执行其它命令,而不用等待后台进程执行完成
守护进程
特殊的后台进程,通常在系统启动时启动,并在系统关闭时停止。它们不与任何终端关联,因此通常不产生任何用户可见的输出。通常通过双重fork来变为守护进程。
守护和后台进程区别:
相同点:
- 守护进程和后台进程都是后台运行
不同点:
-
后台进程一般由用户从终端手动启动的,然后被放到后台运行,例如通过在命令后加 &。
-
后台进程和终端有关联,在终端中启动一个进程并将其放到后台,但该进程仍与这个终端会话关联。如果终端会话结束,后台进程可能也会被终止。通过 nohup command & 可以不接受关闭终端时发送的HUP信号,从而实现持续运行。
-
守护进程一般再系统启动时自动启动,并作为特定的系统用户(而不是启动它的实际用户)运行。它们不与任何终端关联
判断守护进程和后台进程:
-
使用 ps 命令,可以查看进程的 TTY(控制终端)值。守护进程通常不与任何终端关联,所以它们的 TTY 值通常是 ?
-
守护进程的父进程 ID (PPID) 通常是 1
-
手动从终端启动并放入后台的进程是后台进程。而通常在系统启动时自动启动,提供某种服务或功能的进程很可能是守护进程。
-
守护进程通常以特定的非特权用户身份运行,后台进程通常以启动它的用户的身份运行。
孤儿进程和僵尸进程
孤儿进程:
-
当一个子进程比其父进程先结束,而父进程没有调用wait()或相关函数来收集子进程的结束状态,这个已经结束的子进程就会成为僵尸进程。
-
在ps命令输出中,僵尸进程通常显示为Z状态。
僵尸进程:
-
当父进程在其子进程之前结束时,子进程就变成孤儿进程。
-
孤儿进程会被PID为1的进程收养
父子进程
当一个进程启动另一个进程时,启动进程成为“父进程”,而被启动的进程成为“子进程”。
子进程继承了父进程的许多属性,如环境变量。
fork
-
fork() 是C语言在UNIX和Linux系统上用于进程创建的一个系统调用。当一个进程(我们通常称之为“父进程”)调用fork()时,它创建一个新进程(称为“子进程”)。
-
创建的这个子进程几乎和父进程一摸一样,可以将fork()操作理解为将当前的进程复制一份。
-
fork出来的进程是调用fork()进程的子进程。
双重fork过程
1、A进程执行fork操作生成一个和自己一摸一样的子进程B,此时A终止,B成为孤儿进程,随即被PID为1的进程收养。
2、因为守护进程不应该有控制终端,所以要确保守护进程不会意外地获取一个。先让B成为会话领导,然后执行fork操作,生成了和B一摸一样的进程C,B立即终止。
由于B是会话领导,并已经终止,因此C不可能是这个会话的领导。这确保了C不会重新获得控制终端,即使它尝试打开一个。