进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端
2016-04-09 19:24
375 查看
摘要:本文主要介绍进程的基本属性,基本属性包括:进程ID、父进程ID、进程组ID、会话和控制终端.
进程基本属性
#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).
运行后使用“ps u”命令查看对照一下.
#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.
运行后使用“ps u”命令查看对照一下.
#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).
pid ppid pgid
parent: 4924 3633 4924
child: 4926 4924 4924
child: 4925 4924 4924
child: 4927 4925 4924
#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.进程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; }
pid ppid pgid
parent: 4924 3633 4924
child: 4926 4924 4924
child: 4925 4924 4924
child: 4927 4925 4924
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()之前该进程就有一个控制终端,那么这种联系也会中断
相关文章推荐
- 在c语言学习中的问题(一):数组指针,指针数组,二维数组的理解与区分
- View 的位置参数
- Linux内核如何装载和启动一个可执行程序
- HDU 1062 Text Reverse
- HDU 1106 排序(切割字符串)
- ZOJ 3042 City Selection II 【序】【离散化】【数学】
- c++第三次实验——作业
- 未重新服务器而导致的错误java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is
- B. Seating On Bus
- 冒泡排序
- hdu 1243(LCS变形)
- C++——多次free和delete导致错误
- 字符串函数的实现
- 一行命令统计iOS工程代码总行数
- 黄金点游戏
- [BZOJ1059] [ZJOI2007] 矩阵游戏 - 二分图匹配
- 《Android 开发艺术探索》读书笔记一 Activity的生命周期
- Red and Black
- 一些ps会遇到的问题
- MyBatis-Generator自动生成基本代码