更多学习资源尽在Linux学习总结
进程间关系分为进程组、作业、会话。
概念:进程组是一个或多个进程的集合 特点:
每个进程除了有自己的进程ID之外,还属于一个进程组进程组与同一个作业相关联,可以接收来自同一终端的各种信号。每个进程组都有一个唯一的进程组ID,每个进程都可以有一个组长ID组长进程ID等于进程组ID,组长进程可以创建一个进程组,创建一个进程组中的进程。只要该进程组中还有一个进程,那么这个进程组就还存在,哪怕进程组长终止。eg:
&:表示将进程放入后台5574,5575,5576,5577都是进程ID,它们同属于一个5574进程组,组长为5574
特点:
Shell分前后台,它控制的不是进程而是作业或者进程组
一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成Shell可以运行一个前台作业和多个后台作业,这叫做进程控制作业和进程组的区别:如果作业中的某个进程创建了子进程,那么子进程不属于作业一旦作业运行结束,Shell就自己提到前台来,但是子进程还在,子进程又不属于作业。如果原来的前台进程还存在,这个子进程还没有终止,它自动变为后台进程组前台新起作业,Shell是无法运行的,因为它被提到了后台,只有前台作业终止了,Shell才会被提到前台,可以接受用户输入。 eg: #include <stdio.h> #include <unistd.h> int main() { pid_t id = fork(); if(id < 0) { perror("fork"); return 1; } else if(id == 0) { //子进程 while(1) { printf("child(%d): I am running!\n", getpid()); sleep(1); } } else { //父进程 int i = 5; while(i) { printf("parent(%d): I am going to dead ... %d\n", getpid(), i--); sleep(1); } } return 0; } 当运行该程序时,你会发现前台新起了一个作业,为父进程,父进程先在前台运行5s,5s之内前台不接受任何指令,因为shell被提到后台去了但是5s结束后,父进程退出,此时shell被提到其前台,此时输入命令,shell可以处理。因为父进程退出,子进程还在但是子进程不属于父进程那个作业,所以它被提到后台我们发现子进程所属的进程组还在,组长还是父进程,并且还在不断的while循环打消息,还不能用Ctul+c终止,只可以用kill -9 PID杀死
会话是一个或多个进程组的集合。
一个会话可以有一个控制终端,这通常是登录到其上的的终端设备(在终端登录情况下)或伪终端设备(在网络登录情况下)建立与控制终端连接的会话首进程被称为控制进程,一个会话中的进程组可被分为一个前台进程组或一个或多个后台进程组(前台进程组只有一个)所以一个会话中要包括一个控制进程,一个前台进程组或和任意多个后台进程组
其中SI会话id:4120,四个进程同属于一个进程组,一个会话,那么4120又属于谁呢?
可以看出,4120属于bash,bash就是我们说的会话首进程
守护进程也叫精灵进程,是一种运行在后台的特殊进程
特点: 独立于控制终端并且周期性运行某种任务或等待处理某些发生的事件因为没有控制终端所以无法和用户交互不受用户登录和注销的影响作用守护进程是一种很有用的进程,满足于特殊的进程需求比如:Linux大多数服务器就是守护进程
ps axj | more查看守护进程
参数a代表列出所有用户进程参数x代表列出有无控制终端的进程参数j代表列出与作业控制相关的信息
TPGID一栏写着-1的表示没有控制终端的进程,即守护进程。
COMMAND一列⽤用[]括起来的名字表⽰示内核线程,这些线程在内核⾥里创建,没有⽤用户空间代码,因此没有程序⽂文件名和命令⾏行, 通常采⽤用以k开头的名字,表⽰示Kernel。可以看出守护进程通常采⽤用以d结尾的名字,表⽰示Daemon。
查看守护进程:TPGID一栏为-1时表示为守护进程 kill -9 pid杀死守护进程
代码:
#include<stdio.h> int main() { daemon(0,0); while(1) { sleep(1); } return 0; }