8.2ID为0的进程通常是一个调度进程(交换进程),是内核的一部分。ID为1的进程是init进程,在bootstrap进程结束时被内核调用。该进程读写系统初始化文件,引导系统进入某种状态(如多用户)。它是一个普通用户进程,但以超级用户权限运行。8.3函数fork函数声明:#includepid_tfork();特性fork函数是顺序调用的,将父进程的所有文件描述符复制给子进程,即父子进程字符的每个打开文件描述符共享一个文件表项。重要的一点是父进程和子进程共享一个文件偏移量。注意子进程从父进程继承了哪些资源,两者有什么不同。子进程继承继承真实用户ID、有效用户ID、真实组ID、有效组ID设置用户ID标志和设置组ID标志附加组ID会话ID控制终端当前工作目录根目录环境文件方式创建掩码wordsharedmemorysegmentresourcelimitsignalmaskandarrangeforanyopenfiledescriptorclose-on-execflag不继承进程ID子进程父进程的运行时间信息父进程设置的文件锁未处理的信号集theparentprocess父进程未处理的闹钟8.4函数vfork特性在子进程调用exec或exit之前,运行在父进程的空间vfork的使用要谨慎:在子进程调用exec或exit之前,如果子进程修改数据,父进程的数据也会改变。vfork保证子进程先运行,直到调用exec或exit时才可能调用父进程运行。8.5函数exit正常终止返回在主函数调用exit()调用_Exit(),_exit()最后一个线程返回最后一个线程调用phread_exit()异常终止调用abort进程接收到某些信号使进程最后退出ThreadReactstoCancellationpthread_cancel()进程终止时保留的资源ProcessID进程的终止状态该进程使用的CPU时间总量Zombieprocess子进程终止,但父进程没有使用wait或waitpid获取子进程终止状态避免僵尸进程的方法:---1。使用wait或waitpid回收终止进程的资源---2。编写如下代码intmain(){pid_tpid1;if((pid=fork)==0){//为简单起见,不考虑“pid<0”pid_tpid2;if((pid2=fork())==0){while(1){/*grandchildfunc*/}}exit(0);}if(wait(NULL)!=pid1)err_sys("waiterr.");while(1){/*mainthreadfunc*/}exit(0);}代码图当child1提前终止时,child2的父进程变成init,当child2终止时,init调用wait回收僵尸进程的资源8.6functionwaitandwaitpidpid_twait(int*status);pid_twaitpid(pid_tpid,int*status,intoptions);pid:---1.pid==-1,等待任何进程---2。pid>0,等待进程pid---3。pid==0,等待这个进程组的任何进程---4。pid<-1,等待组ID等于pid的绝对值的任何进程选项:---1。WNOTHANG如果没有进程报告状态则立即返回---2。W继续---3。WUNTRACED子进程由于SIGTTIN、SIGTTOU、SIGTSTP或SIGSTOP信号进入挂起状态 ---4。0 status:返回值wait:唯一的错误是进程没有子进程,errno=ECHILDwaitpid:指定的进程或进程组不存在或没有权限调用,那么就会出错8.7函数waitid8.8functionwait3andwait48.10functionexec6execfinallycallexecvefunctionv:vectorl:liste:environmentp:path(notpathname)基本过程控制原语:fork,exec,wait,exitexeclexecleexeclp的命令行参数格式:char*arg0,char*arg1,...,char*argn,(char*)0新程序从调用进程继承的属性:进程ID和父进程ID实际用户ID和实际组ID注:SUID不继承添加组ID进程组ID会话ID控制终端当前工作目录根目录资源限制闹钟剩余时间文件创建掩码字文件锁进程信号掩码挂起信号tms_utime、tms_stime、tms_cutime和tms_ustime值8.11改变用户ID和改变组IDintsetuid(uid_tuid);intsetgid(gid_tuid);intseteuid(uid_tuid);intseteuid(uid_tuid);intsetegid(gid_tuid);intsetreuid(uid_truid,uid_teuid);intsetregid(uid_truid,uid_teuid);intgetresuid(uid_truid,uid_teuid,uid_tsuid);intgetresgid(uid_trgid,uid_tegid,uid_tsgid);ruid,euid,suid转换