linux 进程的pid分配策略——pid位图算法
在研究进程fork()的时候,这个调用了do_fork(),其中do_fork()又涉及到进程的pid分配,这个东西的源代码有许多个版本,而且各自都不是一样的。昨天晚上研究了一晚上,今天从下午研究到现在,总算把内核中pid位图算法有一个整体的把握了。明天早上继续完成这篇博客,现在小小的庆祝一下,明天完成。
typedef struct pidmap
{unsigned int nr_free;char page[4096];
} pidmap_t;
unsigned long mask = 1UL << (offset & (sizeof(unsigned long) * BITS_PER_BYTE - 1));
unsigned long *p = ((unsigned long*)addr) + (offset >> (sizeof(unsigned long) + 1));
其实上面的话,如果在32位机子上运行的话,可以进行如下简化:
unsigned long mask = 1UL << (offset & 31);
unsigned long *p = ((unsigned long*)addr) + (offset >> 5);
#include <stdio.h>/* max pid, equal to 2^15=32768 */
#define PID_MAX_DEFAULT 0x8000/* page size = 2^12 = 4K */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)#define BITS_PER_BYTE 8
//4k*8 32768
#define BITS_PER_PAGE (PAGE_SIZE * BITS_PER_BYTE)
//7fff
//0111 1111 1111 1111
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1)typedef struct pidmap
{unsigned int nr_free;char page[4096];
} pidmap_t;static pidmap_t pidmap = { PID_MAX_DEFAULT, {0}};static int last_pid = -1;static int test_and_set_bit(int offset, void *addr)
{unsigned long mask = 1UL << (offset & (sizeof(unsigned long) * BITS_PER_BYTE - 1));unsigned long *p = ((unsigned long*)addr) + (offset >> (sizeof(unsigned long) + 1));unsigned long old = *p;*p = old | mask;return (old & mask) != 0;
}static void clear_bit(int offset, void *addr)
{unsigned long mask = 1UL << (offset & (sizeof(unsigned long) * BITS_PER_BYTE - 1));//取offset的后31位数据,并左移unsigned long *p = ((unsigned long*)addr) + (offset >> (sizeof(unsigned long) + 1));//+优先级高于>>unsigned long old = *p;*p = old & ~mask;
}static int find_next_zero_bit(void *addr, int size, int offset)
{unsigned long *p;unsigned long mask;while (offset < size){p = ((unsigned long*)addr) + (offset >> (sizeof(unsigned long) + 1));mask = 1UL << (offset & (sizeof(unsigned long) * BITS_PER_BYTE - 1));if ((~(*p) & mask)){break;}++offset;}return offset;
}static int alloc_pidmap()
{int pid = last_pid + 1;int offset = pid & BITS_PER_PAGE_MASK;//把offset的最高为变为0,其他的不变if (!pidmap.nr_free){return -1;}offset = find_next_zero_bit(&pidmap.page, BITS_PER_PAGE, offset);if (BITS_PER_PAGE != offset && !test_and_set_bit(offset, &pidmap.page)){--pidmap.nr_free;last_pid = offset;return offset;}return -1;
}static void free_pidmap(int pid)
{int offset = pid & BITS_PER_PAGE_MASK;pidmap.nr_free++;clear_bit(offset, &pidmap.page);
}int main()
{int i;for (i = 0; i < PID_MAX_DEFAULT; ++i) {printf("pid = %d\n", alloc_pidmap());}return 0;
}
linux 进程的pid分配策略——pid位图算法相关推荐
- Linux 进程管理剖析--转
地址:http://www.ibm.com/developerworks/cn/linux/l-linux-process-management/index.html Linux 是一种动态系统,能够 ...
- linux进程pid分配规则,Linux进程pid分配法
一. 概述 Android系统创建进程,最终的实现还是调用linux fork方法,对于linux系统每个进程都有唯一的 进程ID(值大于0),也有pid上限,默认为32768. pid可重复利用,当 ...
- linux查看pid 对应的程序_资深程序员总结:分析 Linux 进程的 6 个方法,我全都告诉你...
(给Linux爱好者加星标,提升Linux技能) 作者:LemonCoder(本文来自作者投稿) 操作系统「进程」是学计算机都要接触的基本概念,抛开那些纯理论的操作系统底层实现,在Linux下做软件开 ...
- linux命令获取进程pid_如何使用命令获取Linux进程的PID?
PID或进程ID是标识进程的唯一编号.它们是由Linux内核在运行时创建的,进程调度程序控制着它们的CPU活动.因此,无论何时调用应用程序,内核都会首先产生必要的进程并为它们分配这些唯一的PID值.一 ...
- linux进程简介,及PID
在 Linux 底下执行一个指令时,系统会给予这个动作一个 ID, 我们称为 PID,而根据启用这个指令的使用者与相关的指令功能,而给予这个特定 PID 一组权限, 该指令可以进行的行为则与这个 PI ...
- linux进程号是几位数,Linux 进程 PID 编号最大为多少
问题中提到,通过提问者的测试(Ubuntu18.04操作系统下),Python脚本实现的分配进行pid脚本,渠道系统自动分配给进程的最大pid值是131070,这是一个并不特殊的值.(通常可以想到的上 ...
- [ Linux ] 进程概念,pcb,查看进程,pid,ppid,fork
文章目录 一.进程 1.1 基本概念 1.2 描述进程 - PCB 1.3 查看进程 1.3.1 第一种方式 1.3.2 第二种方式 1.4 通过系统调用获取进程标识符 1.4.1 获取进程的pid ...
- linux进程隐藏 hook readdir函数 挂载覆盖/proc/pid 目录
前言 上篇介绍了如何在有源码的情况下,通过 argv[] 及 prctl 对进程名及参数进行修改,整篇围绕/proc/pid/目录和 ps.top 命令进行分析,做到了初步隐藏,即修改了 /proc/ ...
- linux根据pid查看进程,linux根据pid获取进程名和获取进程pid(c语言获取pid)
2013 Liunx中通过进程名查找进程PID可以通过 pidof [进程名] 来查找.反过来 ,相同通过PID查找进程名则没有相关命令.在linux根目录中,有一个/proc的VFS(虚拟文件系统) ...
- linux+pid的管理,Linux 进程管理
以下是Process Management使用的常用命令 - bg,fg,nohup,ps,pstree,top,kill,killall,免费,正常运行时间,很好. 与过程一起工作 快速提示:Lin ...
最新文章
- iOS的相对路径和绝对路径
- C++ 之 string
- PHP 拷贝图像 imagecopy 与 imagecopyresized 函数
- 初中学历怎么学计算机管理,初中学历能否学习计算机
- 业余学python数据挖掘怎么赚钱_0基础转行学Python,学到什么地步能拿到月薪15k+?...
- 用python实现自己的小说阅读器
- 信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...
- php 网络图片 转本地,PHP将Base64图片转换为本地图片并保存
- python初始环境安装
- 华为笔试题——分礼物
- 初学者对于SVM的一点点学习心得
- 电感耦合等离子体发射光谱法测定水样中的金属含量
- Linux电镜分析,环境扫描电子显微镜特点
- 【手把手教你】搭建神经网络(3D点云分类)
- 开放式社区?太小儿科了,智慧城市才是重点
- Android 微软雅黑、仿宋、黑体的使用
- 蓝牙耳机南卡和vivo哪个好用?南卡与vivo实际评测!
- 如何使用 PyTorch 训练自定义关键点检测模型
- 实现悬浮球的桌面显示
- 社保能找公司代缴吗?小心问题找上门
热门文章
- asp.net编程基础
- HDU - 1520 Anniversary party (有向入门树形DP)
- dfs序七个经典问题[转]
- 利用iisnode模块,让你的Node.js应用跑在Windows系统IIS中
- 【OOM】GC overhead limit exceeded
- petshop4.0 详解之五(PetShop之业务逻辑层设计)(转帖)
- web安全day5:DNS部署与安全
- H3C Private VLAN(私有vlan) 实验
- CocosCreator2.3.1按钮节点防止多次连续点击
- 十七、K8s+gitlab+Jenkins建立CI/CD解决方案