国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > 从Cts测试testCheckForDuplicateOutput到linux kernel中Thread消耗PID

从Cts测试testCheckForDuplicateOutput到linux kernel中Thread消耗PID

来源:程序员人生   发布时间:2015-03-30 08:38:41 阅读次数:4499次

最近折腾CTS

android.security.cts

testCheckForDuplicateOutput项,单项测试很容易过,但是联测就挂了。


源码:http://xdecay.com/docs/android-sdk/cts/tests/tests/security/d0/db5/_cloned_secure_random_test_8java_source.php

测试的原理是:不停的创建和关闭进程,测试Pass的条件是出现两个Pid相同的进程。
循环进程以下:
a). 创建进程A, 记录下A的Pid为pid⑴; 然后立即Kill pid⑴;
b). 创建进程B, 记录下B的Pid为pid⑵; 然后立即Kill pid⑵;
……
直到再次出现记录过的进程号。

由于Linux的PId数是有限的,
根据鸽巢原理(n个盒子装n+1个球,必定出现1个盒子有两个球的现象),假定PID的上线时pid_max, 那末如果创建pid_max+1个进程(其实不同时存在),那末
必定会再次出现之前出现过的进程号。


 CTS 测试为了加快测试速率,调用了以下的函数(wastePids):
比如 第1次是pid⑴, 屡次循环以后还未出现同PID的进程号,比如这时候出现了pid⑸000,那末就调用wastePids(1,5000)

/** * This is an attempt to get the PIDs to roll over faster. Threads use up * PIDs on Android and spawning a new thread is much faster than having * another service spawned as we are doing in this test. */ private static void wastePids(int firstPid, int previousPid) { int distance = (firstPid - previousPid + MAX_PID) % MAX_PID; // Don't waste PIDs if we're close to wrap-around to improve odds of // collision. if ((distance < PID_WASTING_SKIP_LOWER) || (MAX_PID - distance < PID_WASTING_SKIP_UPPER)) { return; } for (int i = 0; i < distance; i++) { Thread t = new Thread(); t.start(); } }

按注释翻译而言,应当是通过创建Thread ,将可分配的剩下的Pid占用掉,让Pid尽快循环复用。

问题来了:从传统的thread学习而言,thread怎样会占用Pid,Linux书籍都会告知我们,所有同1个进程下的thread同享1个Pid;更何况,JVM的线程跟Pthread的线程还不是1个东西,因此迷惑了。


查了linux内核的书籍,基本不怎样讲述thread, 这主要是pthread是1个库,而不是Linux内核本身的1部份。


然后开始翻墙google。

找到3篇文章:

第1篇:http://www.cnblogs.com/princessd8251/articles/3914434.html
这篇文章,测试JVM能开辟的最大线程数:  发现线程数量在到达32279以后,不再增长。查了1下,32位Linux系统可创建的最大pid数是32678,这个数值可以通过/proc/sys/kernel/pid_max来做修改(修改方法同threads-max),但是在32系统下这个值只能改小,没法更大。
虽然实际线程数,可以通过修改内核来创建更多线程,但这表明,线程数跟Pid_max是有关的;

第2篇:http://www.ibm.com/developerworks/cn/linux/kernel/l-thread/

这篇文章分析Linux 线程实现机制
虽然,在线程库里面,pthread的创建,使用的是多个线程share 同1个PID,但是,内核确有自己的机制:
Linux内核其实不支持真正意义上的线程,LinuxThreads是用与普通进程具有一样内核调度视图的轻量级进程来实现线程支持的。这些轻量级进程具有独立的进程id,在进程调度、信号处理、IO等方面享有与普通进程1样的能力。

这句话就表明了,内核中,采取的是轻量级的进程来支持线程的调度的,那末必定会占用Pid:

第3篇:http://blog.chinaunix.net/uid⑵7767798-id⑶470592.html

讲述了Pid的分配进程:alloc_pidmap:


static int alloc_pidmap(struct pid_namespace *pid_ns) { int i, offset, max_scan, pid, last = pid_ns->last_pid; //取出last_pid struct pidmap *map; pid = last + 1; //这里last+1,获得备选pid //如果pid到了pidmax,那末重头开始寻觅可用的pid,从RESERVED_PIDS开始,保存RESERVED_PIDS之前的pid号,默许300 if (pid >= pid_max) pid = RESERVED_PIDS; …… }

指明pid是从低往高分配,当超过pid_max,那末重头开始寻觅可用的pid,从RESERVED_PIDS开始,保存RESERVED_PIDS之前的pid号,默许300


到这里基本就明朗了。


至于Thread如何通过VM进入到内核 参看:http://www.eoeandroid.com/blog⑵1517⑶026.html



生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生