1、一般而言
ID 0:调度进程swapper,系统进程
ID 1:init进程,内核启动的最后启动,系统运行时不会死掉
是普通的用户进程而不是系统进程,必须是超级用户运行
ID2: UNIX下是pagedaemon,支持虚拟内存系统的分页功能
LINUX下是kthreadd
#include
pid_t getpid(void);
pid_t getppid(void);
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
注1:这几个函数都没有错误返回
注2: real user id:who we really are
effective user id: used for file access permission checks
2、fork函数
#include
pid_t fork(void);
对子进程返回0,父进程返回进程ID,-1为错误
所以一般写为:
if ((pid = fork()) < 0) {
err_sys("fork()");
else if (pid == 0) {
...
//child
} else {
...
//parent
}
注1:子进程拷贝父进程的.data .bss stack heap 4个部分,而与
父进程共享.text部分
注2:COW(copy-on-write)方式:其实这5个部分都被内核保护成为
只读,只是需要修改的部分做了一份内存拷贝
注3:fork()之后,无法确认子进程先执行还是父进程先执行,这得
看内核的调度算法
======strlen计算的字符串长度不包含null byte,sizeof包含
strlen是一个函数调用,而sizeof在编译的时候计算长度
这个时候buffer已经被初始化,大小固定
注4:所有的文件描述符(STDIN_FILENO,STDOUT_FILENO...)都被
复制到子进程,2者共享一个filetable entry,共享一样的file
offset(父进程和子进程同步更新)
注5:文件锁不被继承,挂机的alarms和signals都在子进程中被清
空
注6:fork()失败的主要原因,其一是系统当前的进程太多,其二是
同一个real user ID下的进程数太多CHILD_MAX(resource
limit)
3、vfork函数
注1:使用跟fork()一样,它倾向于在子进程使用exec执行另外一个
程序时使用
注2:vfork不拷贝父进程的空间地址给子进程,而是子进程就运行
在父进程的地址空间上
注3:vfork确保子进程先执行,直到子进程调用exec或者exit
4、exit函数
注1:不管一个进程怎样结束,在内核里最终都会执行相同的代码
内核关掉所有进程打开的描述符,释放进程使用的内存等等
注2:如果父进程在子进程之前结束,那么进程1 init进程作为子进
程的父进程
注3:内核为每一个结束的进程都保留着小量的信息,这样即使子
进程异常终止了,父进程还可以获取子进程的退出信息,比
如进程ID,进程终止状态,进程使用的CPU时间等等
注4:zombie----子进程结束了,但父进程没有等到和接受到子进
程的结束状态,用ps命令标为Z的进程
阅读(504) | 评论(0) | 转发(0) |