(1)进程组(作业):代表一个或多个进程的集合。
1)父进程创建子进程时,默认子进程与父进程属于同一进程组,进程组id==第一个进程id(组长id,父进程id)。
2)使用kill -SIGKILL -进程组id(负数) 将整个进程组杀死。
3)只有进程组中还有进程存在,进程组就一直存在,与组长进程是否终止无关。
4)进程组生存周期为进程组中最后一个进程存活时间。
5)一个进程可以为自己或子进程设置进程组id(setpgid)
(2)进程组操作函数
1)获取当前进程的进程组id:getpgrp
pid_t getpgrp(void); //返回调用者的进程组ID
2)获取指定进程的进程组id:getpgid
pid_t getpgid(pid_t pid); //成功返回0,失败返回-1
pid=0时,该函数效果和getpgrp作用相同
3)改变进程组默认所属进程组:setpgid(通常用来加入一个现有的进程组或创建一个新进程组)
int setpgid(pid_t pid ,pid_t pgid); 成功:0 失败:-1
功能:将pid加入到pgid中
注意事项:1>如果想要把子进程设置为新的组,应把setpgid放在fork函数之后,exec函数(执行完后不返回了)之前。
2>改变进程组只有在符合自己权限的情况下才能改变。
(3)会话:一个或多个进程组的集合
1)创建会话
1>创建会话的进程不能使进程组的组长,如果是组长进程,则会出错
2>创建会话的进程会成为新进程组的组长进程
3>一般linux需要root权限(ubuntu不需要)
4>新会话会舍弃原有的控制终端,该会话没有控制终端
5>建立新会话的顺序,先调用fork,父进程终止,子进程调用setsid函数创建会话,称为进程组组长和会话的会长。
2)会话操作函数
1>获取进程组所属会话id:getsid
pid_t getsid(pid_t pid) 成功:返回调用进程的会话id 失败:-1
pid=0 查看当前进程的会话id
ps ajx 参数j代表与控制作业相关的信息,参数a代表所有用户的进程,参数x代表所有控制终端和无控制终端的进程。
2>创建一个新会话,并将自己的id设置为进程组id和新会话id:setsid
pid_t setsid(void) 成功:返回调用进程的会话id 失败:-1
3)会话的作用:创建守护(daemon精灵)进程
1>守护进程的定义:linux后台服务进程,通常独立与控制终端并且周期性地执行某种任务或等待处理某些发生的事情,一般采用以d结尾的名字。
2>守护进程的特点:没有控制终端,不能直接和用户交互,不受用户登录、注销的影响,一直运行着。
3>创建守护进程的流程:
1》创建子进程,父进程退出,所有工作都在子进程中进行形式上体力子控制终端。
2》在子进程中创建新会话(setsid函数),使子进程完全独立出来,脱离控制。
3》改变当前目录为根目录(chdir函数),防止占用可卸载的文件系统(如挂载在/mnt下的U盘中的程序,就属于可卸载)
4》重设文件权限掩码(umask函数),防止继承的文件创建某些屏蔽字拒绝某些权限,增加守护进程的灵活性。
5》关闭文件描述符,继续的打开文件(0/1/2)不会用到,浪费系统资源,无法卸载,可以重定向到/dev/null文件下。
6》开始执行守护进程核心工作,守护进程退出处理程序模型。
4>创建守护进程例子