1.进程组
/*********************************************************
包含头文件: #include <unistd.h>
函数原型: pid_t getpgrp(void);
函数说明: 同一进程组中的各进程接收来自同一终端的各种信号,每个进程组有一个唯一的进程组ID.
返回值: 调用进程的进程组ID
*******************************************************/
/********************************************************
包含头文件: #include <unistd.h>
函数原型: pid_t getpgid(pid_t pid);
函数说明: 返回进程pid的进程组ID
返回值:若成功,返回进程组ID,若失败,返回-1
注:若pid为0,则返回调用进程的进程组ID
**********************************************************/
vi 9.1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("进程ID: %d\n",getpid());
printf("进程组ID: %d\n",getpgrp());
printf("init 进程组ID: %d\n",getpgid(1));
return 0;
}
/******************************************************
每一个进程组有一个组长进程,组长进程的进程组ID等于其进程ID
某个进程组有一个进程存在,该进程组就存在,进程组的最后一个进程可以终止也可以转移至其他进程组
包含头文件: #include <unistd.h>
函数原型: int setpgid(pid_t pid,pid_t pgid);
函数说明: 加入或创建一个进程组
返回值:若成功,返回0,若出错,返回-1
*****************************************************/
vi 9.2.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
if ((pid = fork()) < 0)
{
printf("fork error\n");
exit(0);
}
else if (pid == 0)
{
printf("in child\n");
printf("进程ID: %d\n",getpid());
printf("进程组ID: %d\n",getpgrp());
if (setpgid(getpid(),getpid()) < 0)
{
printf("setpgid error\n");
exit(0);
}
printf("修改后....\n");
printf("进程ID: %d\n",getpgrp());
exit(0);
}
if (wait(NULL) != pid)
{
printf("wait error\n");
exit(0);
}
printf("in parent\n");
printf("进程ID: %d\n",getpid());
printf("进程组ID: %d\n",getpgrp());
return 0;
}
2.会话
/***********************************************************
包含头文件: #include <unistd.h>
函数原型: pid_t setsid(void);
函数说明: (1):该进程变成新会话的会话首进程,会话首进程是创建该会话的进程,此时,该进程是会话的首进程
(2):该进程成为一个新进程的组长进程,新进程组ID就是调用进程ID
(3:如果该进程没用控制终端.如果该进程在调用setsid之前该进程有控制终端,那么这种联系也会被切断
返回值:若成功,返回进程组ID,若出错,返回-1
总结: 如果调用进程的进程ID和进程组ID相同,则setsid会失败,子进程默认继承父进程的进程组ID和会话首进程进程组ID
********************************************************/
/****************************************************
包含头文件: #include <unistd.h>
函数原型: pid_t getsid(pid_t pid);
函数说明:返回调用者会话进程pid的会话首进程ID的进程组ID
返回值:若成功,返回会话首进程的进程组ID,若出错,返回-1
*****************************************************/
vi 9.3.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
printf("in parent\n");
pid_t sid;
pid_t pgid;
pid_t pid;
if ((pid = fork()) < 0)
{
printf("fork error\n");
exit(0);
}
else if (pid == 0)
{
printf("in child\n");
printf("进程ID: %d\n",getpgrp());
pid_t ge;
if ((ge = getsid(0)) < 0)
{
printf("getsid error\n");
exit(0);
}
printf("会话首进程进程组ID: %d\n",ge);
if ((pgid = setsid()) < 0)
{
printf("setsid error\n");
exit(0);
}
pid_t get;
if ((get = getsid(0)) < 0)
{
printf("getsid error\n");
exit(0);
}
printf("会话首进程的进程组ID: %d\n",get);
printf("进程组ID: %d\n",getpgrp());
exit(0);
}
printf("进程ID: %d\n",getpid());
if ((sid = getsid(0)) < 0)
{
printf("getsid error\n");
exit(0);
}
printf("进程组ID: %d\n",getpgrp());
printf("会话首进程进程组ID: %d\n",sid);
return 0;
}
/**********************************************************
包含头文件: #include <unistd.h>
函数原型: pid_t tcgetpgrp(int fd);
函数说明: 返回前台进程组ID,它与在fd上打开的终端相关联
返回值:若成功,返回前台进程组ID,若出错,返回-1
*********************************************************/
/*******************************************************
包含头文件: #include <unistd.h>
函数原型: int tcsetpgrp(int fd,pid_t pgrpid);
函数说明:如果进程有一个控制终端,则该进程可以调用
tcsetpgrp将前台进程组ID设置为pgrpid,pgrpid值应当是同一会话中的一个进程组ID,fd必须引用该会话的控制终端
*******************************************************/
/******************************************************
包含头文件: #include <termios.h>
函数原型: pid_t tcgetsid(int fd);
函数说明: 获得会话首进程的进程组ID
返回值: 若成功,返回会话首进程的进程组ID,返回-1
******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t pid;
if ((pid = tcgetpgrp(STDOUT_FILENO)) < 0)
{
printf("tcgetpgrp error\n");
exit(0);
}
printf("进程ID: %d\n",getpid());
printf("标准输出流前台进程组ID : %d\n",pid);
return 0;
}