进程 是一个正在执行的程序;计算机中正在运行的程序实例;
编程过程中用进程号pid来抽象表示
进程组是一个或多个进程的集合。每个进程组有一个称为组长的进程,组长进程就是其进程号(pid)等于进程组号(gid)的进程(即进程组号等于组长的进程号)。
编程过程中用进程组号pgid来抽象表示
会话则是一个或多个进程组的集合,有唯一一个会话首进程。会话号等于会话首进程的进程号。
会话首进程与控制终端建立连接。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。通常情况下,用户登录后所执行的所有程序都属于一个会话,而其登录 shell则是会话期首进程,并且它所使用的终端就是会话的控制终端
编程过程中用会话号sid来抽象表示
控制终端由会话首进程打开, 该终端就成为该会话的控制终端。一个会话只能有一个控制终端,产生在控制终端上的输入和信号将发送给会话的前台进程组中的所有进程,如果会话首进程终止,则该信号发送到该会话期前台进程组的所有进程。
编程过程中用文件描述符fileds来抽象表示
比如: 当我用cltr +alt +t 快捷键时,会打开一个应用程序bash(也就是shell),bash进对应了一个进程,
ps aux 可以查看bash的进程号
ljw 2141 3.8 0.1 8984 3544 pts/2 Ss 17:41 0:00 bash上边的 2141 即为 bash这个进程的进程号(pid)
如果我继续在该shell下,运行另一个程序A, 则进程A的 父进程就是bash,而且进程A的进程组号等于进程A的进程号,也就是说伴随进程A的产生,产生了一个新进程组。进程A是该新产生的进程组的组长进程。
bash的进程号也是会话号,bash进程也是会话首进程,进程A所在进程组是该会话的前台进程组。
当进程A运行结束后,如果继续在该shell下,运行另一个程序B,那么进程B的 父进程就是bash,而且进程B的进程组号等于进程B的进程号,也就是说伴随进程B的产生,产生了一个新进程组。进程B是该新产生的进程组的组长进程。
bash的进程号也是会话号,bash进程也是会话首进程,进程B所在进程组是该会话的前台进程组。
而bash作为会话首进程,他打开了一个终端
ljw 2141 3.8 0.1 8984 3544 pts/2 Ss 17:41 0:00 bash
该终端也就是上述的 pts/2
综上:可以说 启动bash(shell) 就是启动了一个会话。 该会话下有进程组, 进程组下有进程。。。。。。
你可以看成树形结构““`
注:以下的“ 当前进程” 指被调函数所在的进程
1获取当前进程pid和,当前父进程pid
pid_t getpid(); 返回当前进程的进程号pid
pid_t getppid(); 返回当前进程的父进程pid
2获取进程组号
pid_t getpgid(pid_t pidt);
pidt为0 ,返回当前进程的进程组号
pidt为指定进程的pid时,返回其进程组号
pidt_t getpgrp() ; 返回当前进程的进程组号
3获取会话号
pid_t getsid(pid_t pidt)
pidt为0,返回当前进程的会话号
如果pidt表示的进程与当前进程不属于同一个会话,那么返回出错;
4 通过控制终端获取前台进程组号,会话首进程的进程号
pid_t tcgetpgrp(int filedes) 返回与控制终端(该终端由filedes指定,并且该终端已打开)相关联的前台进程组号
pid_t tcgetsid(int filedes) 返回控制终端的会话首进程的进程号
例子:
源代码:
# include <stdio.h># include <fcntl.h>int main(int argc,char *argv[]){ printf("当前进程号=%d\n",getpid()); printf("当前进程的父进程号=%d\n",getppid()); printf("当前进程所在进程组号=%d\n",getpgrp()); printf("当前进程所在会话号(也是会话首进程号):%d\n",getsid(0)); int fd; fd=open("/dev/pts/1",O_RDWR); printf("当前进程所在会话的前台进程组号:%d",tcgetpgrp(fd)); printf("当前进程所在会话的会话号:%d",tcgetsid(fd));}
执行结果:
ljw@ljw-ubuntu:~$ ./test当前进程号=2006当前进程的父进程号=1952当前进程所在进程组号=2006当前进程所在会话号(也是会话首进程号):1952当前进程所在会话的前台进程组号:2006当前进程所在会话的会话号:1952
ljw@ljw-ubuntu:~$ ps aux | grep 1952ljw 1952 0.4 0.1 8984 3616 pts/1 Ss 17:24 0:00 bash
以上程序执行需要注意的是:
运行程序的终端必须与源代码中打开的终端相同,tcgetsid() 和tcgetpgrp()才能执行成功。
例如上面的例子 我用终端 pts/1 运行 ./test
************************************************************************************************************************
悠然享受和大自然融合之乐。