Linux/Unix分配进程ID的方法以及源代码实现
在Linux/Unix系统中。每一个进程都有一个非负整型表示的唯一进程ID。尽管是唯一的。可是进程的ID能够重用。当一个进程终止后,其进程ID就能够再次使用了。
大多数Linux/Unix系统採用延迟重用的算法,使得赋予新建进程ID不同于近期终止进程所使用的ID,这主要是为了防止将新进程误觉得是使用同一ID的某个已终止的先前进程。本文讨论了Linux/Unix分配进程ID的方法以及源代码实现。
分配进程ID的方法
在大多数Linux/Unix系统中,生成一个进程ID方法是:从0開始依次连续分配,一直到能够分配的最大的进程ID(不同的系统。这个最大值是不一样的,比方有些Linux系统是65536)。一旦到达最大值,又一次从某个值(不同的系统,这个值也是不一样的,比方在Mac OS X和HP-UX系统中,这个值是100)開始依次连续查找那些还没有被使用的ID。这里分配进程ID的方法,存在潜在的安全问题。由于能够从系统获取信息或者提取进程间通信的内容。
考虑到安全问题。部分系统可能用其它方法来分配进程ID,比方随机分配一个进程ID。
不管用什么方法分配进程ID。系统都须要保证每一个进程ID是独一无二的。
Linux系统上分配进程ID的源代码实现
在Linux系统中,内核分配PID的范围是(RESERVED_PIDS, PID_MAX_DEFAULT)。在每一个namespace中。PID是依次连续分配的(在不同的namespace的task能够有同样的ID)。
一旦ID达到分配到达上限(在pseudo-file /proc/sys/kernel/pid_max中能够查看能够分配的最大进程ID),从头開始查找分配PID。下面是相关的源码:
struct pid *alloc_pid(struct pid_namespace *ns)
{
/*省略了一些代码*/
for (i = ns->level; i >= 0; i--) {
nr = alloc_pidmap(tmp);
if (nr < 0)
goto out_free;
pid->numbers[i].nr = nr;
pid->numbers[i].ns = tmp;
tmp = tmp->parent;
}
/*省略了一些代码*/
}
static int alloc_pidmap(struct pid_namespace *pid_ns)
{
int i, offset, max_scan, pid, last = pid_ns->last_pid;
struct pidmap *map; pid = last + 1;
if (pid >= pid_max)
pid = RESERVED_PIDS;
/* and later on... */
pid_ns->last_pid = pid;
return pid;
}
注意在Linux内核中,进程PID实现并不不过一个int标识符号(当然返回给应用程序,PID不过int类型的数值)。相关实现的结构体在/include/linux/pid.h中能够找到。除了ID外。它还包含跟这个ID相关的task列表、引用计数器和一个能够方便查找的hashed list。
进程ID分配须要注意的事项
1、僵尸进程的PID是临时不能用的。须要其父进程收集器全部的终止状态才干使用,也就是说须要调用类似wait()函数后,才干使用。
2、详细实现时,系统能够随机分配进程PID(当然是保证没有被其它进程使用),因此在应用程序中,不要依赖于进程PID的分配方式。
3、在用户空间(user space)可能看到分配的进程ID并不连续,这是由于在应用程序两个fork之间,内核调度程序(scheduling)可能创建了一个进程。
其实。这样的情况是常常发生的。
參考资料
《UNIX环境高级编程》(第二版)
http://superuser.com/questions/135007/how-are-pids-generated
http://stackoverflow.com/questions/3446727/how-does-linux-determine-the-next-pid
http://en.wikipedia.org/wiki/Process_identifier
Linux/Unix分配进程ID的方法以及源代码实现的更多相关文章
- Linux下查找进程id并强制停止进程的脚本
Linux下的tomcat的停止脚本shutdown.sh经常失败,造成tomcat进程没关闭.所以只能手动查找进程id,然后用kill命令来强制停止.每次都要这样查一下,然后再杀进程.感觉有点麻烦, ...
- Linux监控重要进程的实现方法
Linux监控重要进程的实现方法 不管后台服务程序写的多么健壮,还是可能会出现core dump等程序异常退出的情况,但是一般情况下需要在无 人为干预情况下,能够自动重新启动,保证服务进程能够服务用户 ...
- 编写Linux/Unix守护进程
原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开 ...
- 【Linux】- 守护进程的启动方法
转自:Linux 守护进程的启动方法 Linux中"守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问 ...
- linux下查看进程id时用到的命令
一.查看端口占用的进程 . lsof -i:端口号, 查看某一端口的占用情况 [root@localhost bin]# lsof -i: COMMAND PID USER FD TYPE DEVIC ...
- Linux的僵尸进程及其解决方法
1. 产生原因: 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程.通过ps命令查看其带有defunct的标志.僵尸进程是一个 ...
- Linux/UNIX之进程环境
进程环境 进程终止 有8种方式使进程终止,当中5中为正常终止,它们是 1) 从main返回 2) 调用exit 3) 调用_exit或_Exit 4) 最后一个 ...
- Linux&UNIX上卸载GoldenGate的方法
1. Log on to the database server (as oracle) where the GoldenGate software is installed. [root@oracl ...
- 使用Java代码获取Java进程ID的方法
需要jre/lib下的tools.jar包 public class Test { public static void main(String[] args) throws Exception { ...
随机推荐
- String 字符串详解 / 常用API
String 详解 / 常用API 简介 String 是不可改变的字符串序列.String 为字符串常量 StringBuilder 与StringBuffer 均为可改变的字符串序列.为字符串变量 ...
- JBOSS集群和安装
JBOSS集群和安装 http://jijian91.com/blog20071010/jboss-cluster-part5.html http://wing123.iteye.com/blog/3 ...
- codevs 1204 寻找子串位置 KMP
1204:寻找子串位置 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 18K Solved: 8K Description 给出字符串a和字符串b,保 ...
- 【原】Order属性决定了不同切面类中通知执行的先后顺序
[障碍再现] MyBatis配置多数据源时,数据源切换失败. [原因分析] 自定义切面和Spring自带事务切面“即<aop:advisor>”执行的先后顺序导致数据源不能切换成功. ...
- 关于Vue的一些小技巧
前言 用Vue开发一个网页并不难,但是也经常会遇到一些问题,其实大部分的问题都在文档中有所提及,再不然我们通过谷歌也能成功搜索到问题的答案,为了帮助小伙伴们提前踩坑,在遇到问题的时候,心里大概有个谱知 ...
- lykchat+zabbix实现微信告警
http://www.ttlsa.com/zabbix/lykchat-zabbix-wechat-alert/
- 深入理解 Java中的 流 (Stream)
首先,流是什么? 流是个抽象的概念.是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以"流"的方式进行.设备能够是文件,网络,内存等. 流具有方向性,至于是输入 ...
- MVC在基控制器中实现处理Session的逻辑
当需要跨页面共享信息的时候,Session是首当其冲的选择,最典型的例子就是:在处理登录和购物车逻辑的时候需要用到Session.在MVC中,可以把处理Session的逻辑放在一个泛型基控制器中,但需 ...
- UML:概要设计,用什么画我的类图?
背景 做过需求之后,很少使用 UML 画概要设计,这几天尝试的用了几个工具,最总还是选择了 VisualStudio. Edraw 详细信息很难编辑,如:签名. Viso 添加成员太麻烦了. Visu ...
- c++11改进我们的程序之垃圾回收(一)
c#和java中有自己主动垃圾回收机制,.net执行时和java虚拟机能够管理分配的堆内存,在对象失去引用时自己主动回收,因此在c#和jva中, 内存管理不是大问题.c++语言没有垃圾回收机制,必须 ...