1.进程组
每个进程属于一个进程组,进程组是一个或多个进程的集合,每个进程有一个唯一的进程组ID。
获取进程组的两个函数:
#include<unstd.h>
pid_t getpgrp(void);
pid_t getpgrp(pid_t pid);
进程组可以有一个组长进程,组长进程的标识是,其进程组ID等于其进程ID。进程组的生存周期是,从进程组开始创建到最后一个进程离开为止,最后一个进程的离开可以是终止或者转移到另一个进程组,进程组长也可能加入到另一个进程组,原进程组的组ID保持不变。
测试代码:
#include<unistd.h>
#include<iostream>
int main()
{
pid_t pid;
pid = fork();
if (0 == pid) //child
{
std::cout<<"child pid:"<<getpid()<<"\n";
std::cout<<"child grp:"<<getpgrp()<<"\n";
sleep(5);
std::cout<<"child grp:"<<getpgrp()<<"\n";
}
else //father process
{
std::cout<<"father pid:"<<getpid()<<"\n";
std::cout<<"father grp:"<<getpgrp()<<"\n";
}
return 0;
}
运行结果:
father pid:4341
father grp:4341
child pid:4343
child grp:4341
child grp:4341
2.会话
会话是一个或多个进程组的集合,会话首进程是创建此会话的进程,会话首进程的进程ID是会话ID,首进程是其所在的进程组的组长进程,因为在其创建一个会话的同时已经变成了一个组长进程。
没有设置会话ID的api,如果会话首进程改变了其组ID呢? 如果首进程停止了,会话ID会改变吗?
测试代码:
#include<stdio.h>
#include<iostream>
int main()
{
if (0 < fork()) //father
{
return 0;
}
//child
setsid();//建立一个新会话
std::cout<<"f pid:"<<getpid()<<" groupID:"<<getpgrp()<<" sessionID:"<<getsid(0)<<"\n";
pid_t pid = fork();
if(0 == pid)
{
setpgid(0,0);
std::cout<<"chiled pid:"<<getpid()<<" chiled groupID:"<<getpgrp()<<" sessionID:"<<getsid(0)<<"\n";
sleep(1);
std::cout<<"chiled pid:"<<getpid()<<" chiled groupID:"<<getpgrp()<<" sessionID:"<<getsid(0)<<"\n";
return 0;
}
int err = setpgid(0,pid);
std::cout<<"change gid result:"<<err<<"\n";
std::cout<<"f pid:"<<getpid()<<" groupID:"<<getpgrp()<<" sessionID:"<<getsid(0)<<"\n";
return 0;
}
测试结果:
f pid:8696 groupID:8696 sessionID8696
change gid result:-1
f pid:8696 groupID:8696 sessionID8696
chiled pid:8698 chiled groupID:8698 sessionID 8696
chiled pid:8698 chiled groupID:8698 sessionID 8696
从测试结果看,首进程无法改变其组ID,首进程退出后,此会话的会话ID不变