每个进程都有一个非负整型表示的唯一进程ID。
系统有一些专用的进程:
ID为0的进程常为调度进程(swapper),改进程是内核的一部分,不执行任何磁盘上的程序,因此也被称为系统进程。
ID为1的进程常为init进程,在自举过程(bootstrap procedure)结束由内核调用。负责在自举内核后启动一个UNIX系统。init通常读与系统有关的初始化文件(/etc/rc*文件或/etc/inittab文件,以及/etc/init.d中的文件),并将系统引导到一个状态(例如多用户)。init进程绝不会终止,它是一个普通的用户进程,不是内核的系统进程,但是它以超级用户特权运行。
fork,子进程是父进程的副本。子进程获得父进程数据空间、堆和栈的副本。父子进程不共享这些存储空间部分,他们共享正文段。
由于fork之后经常跟随一个exec,所以现在很多实现使用了写时复制(COW)技术。
以前知识:write函数是不带缓冲的。
标准I/O库是带缓冲的。如果标准输出连到终端设备,则它是行缓冲的,否则它是全缓冲的。
文件共享
vfork与fork一样都创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是也就不会访问该地址空间。而且vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。
进程的终止,不管经过哪种方式终止,最后都会执行内核中的同一段代码。这段代码为相应进程关闭所有打开描述符,释放它所使用的存储器等。
在任意一种情况下,该终止进程的父进程都能用wait或waitpid函数取得其终止状态。
僵尸进程:一个已经终止,但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它占用的资源)的进程。
wait,waitpid函数
当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。
pid_t wait(int * statloc);
pid_t waitpid(pid_t pid, int* statloc , int options);
区别:1.在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞。
2.waitpid并不等待在其调用之后的第一个终止子进程,它有若干个选项,可以控制它所等待的进程。
程序清单8-5结果:
6种exec:
调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用一个全新的程序替换了当前程序的正文,数据,堆和栈段。
记忆exec函数的参数:字母p表示取filename作为参数,并用PATH环境变量寻找可执行文件。字母l表示取一个参数表,它与字母v互斥。v表示取一个argv[]。最后,字母e表示取envp[]数组,而不使用当前环境。
在执行exec前后实际用户ID和实际组ID保持不变,而有效ID是否改变取决于所执行程序文件的设置用户ID位和设置组ID位是否设置。如果新程序的设置用户ID位已设置,则有效用户ID编程程序文件所有者的ID,否则有效用户ID不变。对组ID的处理方式与此相同。
更改用户ID和组ID
int setuid(uid_t uid);设置实际用户ID和有效用户ID
int setgid(gid_t gid);设置实际组ID和有效组ID
1)进程有超级用户特权。setuid将实际用户ID,有效用户ID,以及保存的设置用户ID设置为uid;
2)若无超级用户特权,但uid=实际用户ID或保存的设置用户ID,则setuid只讲有效用户设置为uid;
3)若以上两个条件都不满足,则error设置为EPERM,并返回-1。
关于内核所维护的三个用户ID,需注意:
1)只有超级用户进程可以更改实际用户ID。e.g.login是一个超级用户进程,可在用户登录时,设置实际用户ID。
2)仅当对程序文件设置了设置用户ID时,exec函数才会设置有效用户ID。
3)保存的设置用户ID是由exec复制有效用户ID而得来的。
解释器文件
起始行的形式是 #!pathname [optional-argument] e.g.常见 #!/bin/sh
对这种文件的识别是由内核作为exec系统调用处理的一部分来完成的。内核使调用exec函数的进程实际执行的是该解释器文件第一行中的pathname所指定的文件。
system函数
int system(const char * cmdstring);
system在其实现中调用了fork,exec,waitpaid。
进程会计
acct函数用于启动和禁用进程会计。accton命令使用此函数。
会计文件中记录的顺序对应于进程终止的顺序,而不是它们启动的顺序。
用户标识
char *getlogin(void); 用此函数通常可以获取用户登录时使用的名字。
给出登录名后,就可以使用getpwnam在口令文件中查找用户的相应记录。