Kernel 内核如何确定下一个pid?
我试图理解FreeBSD内核如何分配PID 我发现:Kernel 内核如何确定下一个pid?,kernel,freebsd,Kernel,Freebsd,我试图理解FreeBSD内核如何分配PID 我发现: 186静态int-randompid=0; 187 188静态整数 189 sysctl\u kern\u randompid(sysctl\u HANDLER\u ARGS) 190 { 191整数误差,pid; 192 193错误=sysctl_wire_old_缓冲区(req,sizeof(int)); 194如果(错误!=0) 195返回(错误); 196 sx锁和allproc锁; 197 pid=随机pid; 198错误=sysc
186静态int-randompid=0;
187
188静态整数
189 sysctl\u kern\u randompid(sysctl\u HANDLER\u ARGS)
190 {
191整数误差,pid;
192
193错误=sysctl_wire_old_缓冲区(req,sizeof(int));
194如果(错误!=0)
195返回(错误);
196 sx锁和allproc锁;
197 pid=随机pid;
198错误=sysctl\u handle\u int(oidp和pid,0,req);
199如果(错误==0&&req->newptr!=NULL){
200如果(pid<0 | | pid>pid_max-100)/*超出范围*/
201 pid=pid_最大值-100;
202如果(pid<2)/*NOP*/
203 pid=0;
204否则,如果(pid<100)/*使其合理*/
205 pid=100;
206随机pid=pid;
207 }
208 sx_xunlock(和allproc_lock);
209返回(错误);
210 }
211
212 SYSCTL_PROC(_kern,OID_AUTO,randompid,CTLTYPE_INT | ctlfag_RW,
213 0,0,sysctl_kern_randompid,“I”,“随机PID模”);
214
215静态整数
216 fork_findpid(int标志)
217 {
218结构程序*p;
219-胰蛋白酶;
220静态整数=0;
221
222 /*
223*需要allproc_锁才能遍历列表
224*个进程,并使用proctree_锁访问p_pgrp。
225 */
226 sx_断言(&allproc_lock,sx_lock);
227 sx_断言(&proctree_lock,sx_lock);
228
229 /*
230*查找未使用的进程ID。我们记住一系列未使用的ID
231*随时可用(从上次PID+1到PID-1)。
232 *
233*如果设置了RFHIGHPID(在系统引导期间使用),则不分配
234*低编号PID。
235 */
236 trypid=lastpid+1;
237如果(标志和RFHIGHPID){
238如果(胰蛋白酶<10)
239胰蛋白酶=10;
240}其他{
241如果(随机PID)
242 trypid+=arc4random()%randompid;
243 }
244重试:
245 /*
246*如果流程ID原型已缠绕,
247*重新启动略高于0,因为编号较低的程序
248*倾向于包括不退出的守护进程。
249 */
250如果(trypid>=pid_max){
251 trypid=trypid%pid_max;
252如果(胰蛋白酶<100)
253胰蛋白酶+=100;
254=0;
255 }
256如果(trypid>=pidchecked){
257 int doingzomb=0;
258
259 PID检查=PID_最大值;
260 /*
261*扫描活动和僵尸程序以检查此pid
262*正在使用中。记住最低pid值更大
263*比trypid高,所以我们可以暂时避免检查。
264 */
265 p=列表_优先(&allproc);
266再次:
267 for(;p!=NULL;p=LIST_NEXT(p,p_LIST)){
268而(p->p_pid==trypid||
269(p->p_pgrp!=NULL&&
270(p->p_pgrp->p_id==trypid||
271(p->p_会话!=空&&
272 p->p_session->s_sid==trypid){
273胰蛋白酶++;
274如果(trypid>=pidchecked)
275转去重试;
276 }
277如果(p->p_-pid>trypid&&pidchecked>p->p_-pid)
278 pidchecked=p->p_pid;
279如果(p->p_pgrp!=NULL){
280如果(p->p_pgrp->p_id>trypid&&
281(检查>p->p_pgrp->p_id)
282 pidchecked=p->p_pgrp->pg_id;
283如果(p->p_会话!=空&&
284 p->p_会话->s_sid>trypid&&
285 pidchecked>p->p_session->s_sid)
286 pidchecked=p->p_session->s_sid;
287 }
288 }
289如果(!doingzomb){
290 doingzomb=1;
291 p=列表第一(&zombproc);
292又去了;
293 }
294
296 /*
297*RFHIGHPID在引导期间不会与lastpid计数器发生冲突。
298 */
299如果(标志和RFHIGHPID)
300=0;
301其他
302 lastpid=trypid;
303
304返回(trypid);
305 }
306
但我有几个问题:
186 static int randompid = 0;
187
188 static int
189 sysctl_kern_randompid(SYSCTL_HANDLER_ARGS)
190 {
191 int error, pid;
192
193 error = sysctl_wire_old_buffer(req, sizeof(int));
194 if (error != 0)
195 return(error);
196 sx_xlock(&allproc_lock);
197 pid = randompid;
198 error = sysctl_handle_int(oidp, &pid, 0, req);
199 if (error == 0 && req->newptr != NULL) {
200 if (pid < 0 || pid > pid_max - 100) /* out of range */
201 pid = pid_max - 100;
202 else if (pid < 2) /* NOP */
203 pid = 0;
204 else if (pid < 100) /* Make it reasonable */
205 pid = 100;
206 randompid = pid;
207 }
208 sx_xunlock(&allproc_lock);
209 return (error);
210 }
211
212 SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW,
213 0, 0, sysctl_kern_randompid, "I", "Random PID modulus");
214
215 static int
216 fork_findpid(int flags)
217 {
218 struct proc *p;
219 int trypid;
220 static int pidchecked = 0;
221
222 /*
223 * Requires allproc_lock in order to iterate over the list
224 * of processes, and proctree_lock to access p_pgrp.
225 */
226 sx_assert(&allproc_lock, SX_LOCKED);
227 sx_assert(&proctree_lock, SX_LOCKED);
228
229 /*
230 * Find an unused process ID. We remember a range of unused IDs
231 * ready to use (from lastpid+1 through pidchecked-1).
232 *
233 * If RFHIGHPID is set (used during system boot), do not allocate
234 * low-numbered pids.
235 */
236 trypid = lastpid + 1;
237 if (flags & RFHIGHPID) {
238 if (trypid < 10)
239 trypid = 10;
240 } else {
241 if (randompid)
242 trypid += arc4random() % randompid;
243 }
244 retry:
245 /*
246 * If the process ID prototype has wrapped around,
247 * restart somewhat above 0, as the low-numbered procs
248 * tend to include daemons that don't exit.
249 */
250 if (trypid >= pid_max) {
251 trypid = trypid % pid_max;
252 if (trypid < 100)
253 trypid += 100;
254 pidchecked = 0;
255 }
256 if (trypid >= pidchecked) {
257 int doingzomb = 0;
258
259 pidchecked = PID_MAX;
260 /*
261 * Scan the active and zombie procs to check whether this pid
262 * is in use. Remember the lowest pid that's greater
263 * than trypid, so we can avoid checking for a while.
264 */
265 p = LIST_FIRST(&allproc);
266 again:
267 for (; p != NULL; p = LIST_NEXT(p, p_list)) {
268 while (p->p_pid == trypid ||
269 (p->p_pgrp != NULL &&
270 (p->p_pgrp->pg_id == trypid ||
271 (p->p_session != NULL &&
272 p->p_session->s_sid == trypid)))) {
273 trypid++;
274 if (trypid >= pidchecked)
275 goto retry;
276 }
277 if (p->p_pid > trypid && pidchecked > p->p_pid)
278 pidchecked = p->p_pid;
279 if (p->p_pgrp != NULL) {
280 if (p->p_pgrp->pg_id > trypid &&
281 pidchecked > p->p_pgrp->pg_id)
282 pidchecked = p->p_pgrp->pg_id;
283 if (p->p_session != NULL &&
284 p->p_session->s_sid > trypid &&
285 pidchecked > p->p_session->s_sid)
286 pidchecked = p->p_session->s_sid;
287 }
288 }
289 if (!doingzomb) {
290 doingzomb = 1;
291 p = LIST_FIRST(&zombproc);
292 goto again;
293 }
294
296 /*
297 * RFHIGHPID does not mess with the lastpid counter during boot.
298 */
299 if (flags & RFHIGHPID)
300 pidchecked = 0;
301 else
302 lastpid = trypid;
303
304 return (trypid);
305 }
306