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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)