摘要:本文主要介绍进程的基本属性,基本属性包含:进程ID、父进程ID、进程组ID、会话和控制终端.

进程基本属性

1.进程ID(PID)

函数定义:

     #include <sys/types.h>

     #include <unistd.h>

     pid_t getpid(void);

函数说明:

    每一个进程都有一个非负整型表示的唯一进程ID(PID).好比方我们的身份证一样,每一个人的身份证号是唯一的.由于进程ID标示符总是唯一的,常将其用来做其它标示符的一部分以保证其唯一性。进程ID(PID)是无法在用户层改动的.

    在Linux系统中,PID为0 的进程一般是调度进程。经常被称为交换进程,也是第一个系统进程.第一个用户进程是init进程。其PID为1.

    在应用编程中。调用getpid()函数能够获得当前进程的PID,此函数没有參数,假设运行成功返回当前进程的PID。失败返回-1。出错原因存储于errno.

样例1:打印自己的进程ID(PID).

#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid; //pid_t 事实上是int
pid = getpid();
printf("the current program's pid is %d\n",pid);
while(1);
return 0;
}

执行后使用“ps u”命令查看对比一下.

2.父进程ID(PPID)

函数定义:

     #include <sys/types.h>

     #include <unistd.h>

     pid_t getppid(void);

函数说明:

    不论什么进程(除init进程)都是由还有一个进程创建。该进程称为被创建进程的父进程。被创建的进程称为子进程。父进程ID无法在用户层改动.父进程的进程ID即为子进程的父进程ID(PPID).

    用户能够通过调用getppid()函数来获得当前进程的父进程ID(PPID).此函数没有參数,假设运行成功返回当前进程的父进程ID(PPID)。失败返回-1,出错原因存储于errno.

样例1:打印自己的父进程PPID.

#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t ppid; //pid_t 事实上是int
ppid = getppid();
printf("the current program's ppid is %d\n",ppid);
while(1);
return 0;
}

执行后使用“ps u”命令查看对比一下.

3.进程组ID(process group ID PGID)

函数定义:

    #include <unistd.h>

    int setpgid(pid_t pid, pid_t pgid);

    pid_t getpgid(pid_t pid);

    pid_t getpgrp(void);                 /* POSIX.1 version */

    pid_t getpgrp(pid_t pid);            /* BSD version */

    int setpgrp(void);                   /* System V version */

    int setpgrp(pid_t pid, pid_t pgid);  /* BSD version */

函数说明:

    在Linux系统中。每一个用户都实用户ID(UID)和用户组ID(GUID).相同,进程也拥有自己的进程ID(PID)和进程组ID(PGID). 进程组是一个或多个进程的集合;他们与同一作业相关联.每一个进程组都有唯一的进程组ID(PGID),进程组ID(PGID)能够在用户层改动.比方。将某个进程加入到还有一个进程组,就是使用setpgid()函数改动其进程组ID.

    用户能够通过调用getpgid()函数来获得当前进程的进程组ID(PGID).若此參数为0表示获取当前进程的进程组ID,假设运行成功返回当前进程的进程组ID(PGID)。失败返回-1。出错原因存储于errno. 建议使用POSIX.1规定中的无參数getprgp()函数替代getpgid(pid)函数.

    进程组ID(PGID)也能够通过函数getpgrp()获得.通过fork()函数产生的子进程会继承它的父进程的进程组ID(PGID).

    每一个进程组都能够有一个组长进程,组长进程的进程组ID等于其进程ID.但组长进程能够先退出。即仅仅要在某个进程组中有一个进程存在,则该进程组就存在,与其组长进程是否存在无关.进程组的最后进程能够退出或转移到其它组.

    能够将某个进程增加到某个进程组中,调用系统函数setpgid().其第一个參数为欲改动进程组ID(PGID)的进程ID(PID),第二參数为新的进程组ID(PGID),假设这两个參数相等,则由pid指定的进程变为该进程组组长。假设pid为0,则使用调用者的进程ID(即改动当前进程的进程组ID(PGID为指定的pgid));假设pgid是0,则由pid指定的进程ID(PID)。用做进程组ID(PGID)(即:pid所指进程作为进程组的组长进程).

    一个进程仅仅能为自己或子进程设置进程组ID(PGID),假设在它的子进程中调用了exec()等系列函数,就不再能改变该子进程的进程组ID(PGID).

#include <unistd.h>
#include <stdio.h>
int main()
{
int i;
printf("\t pid \tppid \t pgid\n");
printf("parent:\t%d\t%d\t%d\n",getpid(),getppid(),getpgid(0));
for(i=0; i<2; i++)
{
if(fork()==0)
{
printf("child:\t%d\t%d\t%d\n",getpid(),getppid(),getpgid(0));
}
}
sleep(500);
return 0; }

输出:

4.会话(session)

函数定义:

    #include <unistd.h>

    pid_t getsid(pid_t pid);

    pid_t setsid(void);

函数说明:

    会话是一个或多个进程组的集合.系统调用函数getsid()用来获取某个进程的会话ID(SID).

    假设pid是0。返回调用进程的会话SID,一般说来。改制等于进程组ID(PGID).假设pid并不属于调用者所在的会话。则调用者就无法获取SID.

    某个进程的会话ID也是能够改动的。调用函数setsid()用来创建一个新的会话.

    假设调用进程已经是一个进程组的组长,则此函数返回错误.假设不是,则返回一个新的会话.

(1)该进程变成新会话首进程。会话首进程是创建该会话的进程。此时,该进程是新会话唯一的进程.

(2)该进程成为一个新的进程组的组长进程.新的进程组ID(PGID)是该调用进程的PID.

(3)该进程没有控制终端.假设在调用setsid()之前该进程就有一个控制终端,那么这样的联系也会中断.

 

图1 进程组合会话的进程安排

5.控制终端(controlling terminal)

函数定义:

    #include <unistd.h>

    pid_t tcgetpgrp(int fd);

    int tcsetpgrp(int fd, pid_t pgrp);

函数说明:

    会话和进程组的关系:

(1)一个会话能够有一个控制终端,建立于控制终端相连接的会话首进程被称为控制进程.

(2)一个会话中的几个进程组可被分为一个前台进程组和几个后台进程组,假设一个会话有一个控制终端,则他有一个前台进程组.

(3)不管何时键入终端的中断键,都会将中断信ID发送给前台进程组的全部会话。不管何时键入终端的退出键,都会将退出信ID发送给前台进程组的全部会话.

假设终端监測到调制解调器(或网络)已经断开连接,则将挂断信ID发送给控制进程(会话首进程).

    调用函数tcgetgrpt()获取与打开的终端相关联的前台进程组的进程组ID.

    调用函数tcsetgrpt()设置某个进程组是前台进程还是后台进程组.

    假设进程有一个控制终端,则将前台进程组ID设置为pgrp,pgrp的值应该在同一会话中的一个进程组的ID。fd为控制终端的文件描写叙述符.

    假设调用tcsetpgrp()函数的是会话中的后台进程组的进程,则该进程不会堵塞,或者忽略SIGTTOU信号.信号SIGTTOU将会发送给该进程组的全部进程.

    当fd是指向进程的控制终端,函数tcgetpgrp()返回终端的前台进程组的进程组ID,该ID值是一个大于1且没有使用的值.假设fd指向的不是进程的终端,则函数返回-1,并设置errno指示出错.

 

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwNjEwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" height="327" width="544">

图2 显示控制终端的进程组和会话


笔者:个人能力有限,仅仅是学习參考...读者若发现文中错误,敬请提出.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------勿在浮沙筑高台。静下心来,慢慢地沉淀---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端的更多相关文章

  1. 进程 、进程组、会话、控制终端之间的关系 (转载 http://blog.csdn.net/yh1548503342/article/details/41891047)

    一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的,他们彼此之间或者存在者父子.兄弟关系,或者在功能有相近的联系. 那linux为什么要有进程组呢?其实提供进程组就是方便管理这些进程.假设要 ...

  2. 进程组与会话 Linux Process Groups and Sessions

    在类Unix系统中,用户通常会跟各种相关的进程打交道.虽然在登录的时候只有一个终端进程(用户对应的登录shell ,通过这个shell启动各种程序和服务),但通常不久以后就会产生许多相关的进程,例如进 ...

  3. Linux-进程、进程组、作业、会话、控制终端详解

    一.进程 传统上,Unix操作系统下运行的应用程序. 服务器以及其他程序都被称为进程,而Linux也继承了来自unix进程的概念.必须要理解下,程序是指的存储在存储设备上(如磁盘)包含了可执行机器指 ...

  4. 如何按名称或PID查找一个进程?如何按端口号查找一个进程?如何查看一个进程的CPU和内存、文件句柄使用情况?如何查看CPU利用率高的TOP10进程清单?如何根据PID强制终止进程?

    如何按名称或PID查找一个进程?如何按端口号查找一个进程?如何查看一个进程的CPU和内存.文件句柄使用情况?如何查看CPU利用率高的TOP10进程清单? 目录 如何按名称或PID查找一个进程?如何按端 ...

  5. 【转】linux 设置用户id 设置组id

    linux 设置用户id 设置组id   转自 linux 设置用户id 设置组id   最近看apue,简单记录对设置用户id理解(设置组id同理). 1. 相关的id好像很多,共有哪些? 文件2个 ...

  6. 设置用户ID和设置组ID

    与一个进程关联的ID有6个或更多,如下图所示: 与每个进程相关联的用户ID和组ID 实际用户ID 实际组ID 我们实际是谁 有效用户ID 有效组ID 附加组ID 用于文件访问权限检索 保存的设置用户I ...

  7. 系统数据文件和信息之附加组ID

    4.2BSD引入了附加组ID(supplementary group ID)的概念.我们不仅可以属于口令文件记录项中组ID所对应的组,也可属于多达16个另外的组.文件访问权限检查相应被修改为:不仅将进 ...

  8. 用户id,组id和文件访问权限

    实际用户ID和实际组ID:标示了我们究竟是谁,这两个字段在登录时取自口令文件中的登录项 有效用户ID和有效组ID以及附属组ID:决定了我们的文件的访问权限(通常有效用户ID等于实际用户ID,有效组ID ...

  9. linux保存的设置用户/组ID(set-user-ID)的测试

    直接贴代码和结果 // FileName: id.cpp #include <iostream> #include <unistd.h> using namespace std ...

随机推荐

  1. Switch能否用string做参数

    在Java5以前,switch(expr)中,exper只能是byte,short,char,int类型(或其包装类)的常量表达式. 从Java5开始,java中引入了枚举类型,即enum类型. 从J ...

  2. JquerySession使用

    添加数据 $.session.set('key', 'value') 删除数据 $.session.remove('key'); 获取数据 $.session.get('key'); 清除数据 $.s ...

  3. 纯HTML+CSS写出一颗会飘动的树,有没有惊艳到你呢?

    前言 使用HTML+CSS能写出什么惊人的效果呢? 针对这个问题,我总会看到类似的回答,比如没有JS,前端永远都是静态的:HTML5要搭配JS,要不然一文不值. JS固然强大,但CSS也并非一文不值, ...

  4. 我在16aspx网上下载了个C#源码,如何能在我自己的计算机上跑起来,很急!求详细操作过程!

    先搞清楚是WINDOWS程序还是WEB程序.

  5. [jquery] 给动态生成的元素绑定事件 on方法

    用底下的方法尝试了好多次都失败 $('.del').on('click',function(){ alert('aa'); })// 失败!! 终于在准备放弃前看到一篇博文说的方法 $(documen ...

  6. Usage of API documented as @since 1.6+

    报错:即方法是Java1.6才开始有的 File ->Project Structure->Project Settings -> Modules -> Language Le ...

  7. api访问参数

    一.Get请求 1.一个参数时 2. 二.Post请求

  8. HDU 1171 Big Event in HDU【01背包/求两堆数分别求和以后的差最小】

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

  9. 二分LIS模板

    假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5. 下面一步一步试着找出它. 我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列. ...

  10. 51nod 1133 不重叠的线段【贪心/区间覆盖】

    1133 不重叠的线段 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠的 ...