一 .进程环境
1. 终止函数
三个终止函数,原型为 :
#include<stdlib.h>
void exit(int status);
void _Exit(int status);
#include<unistd.h>
void _exit(int status);
函数exit执行标准I/O库的冲洗关闭操作,这造成输出缓冲区中的所有数据都被冲洗写到文件。status是终止状态。
#include<stdlib.h>
int atexit(void (*func)(void));
函数的参数是个函数地址,调用此函数能够注册终止处理程序,进程终止时调用终止处理程序,调用的顺序与注册的顺序相反。
2.函数setjmp longjmp
goto语句不能跨越函数,执行函数跳转功能的是setjmp与longjmp
#include<setjmp.h>
int setjmp(jmp_buf,env);
void longjmp(jmp_buf env,int val);
setjmp位于希望返回的地方,第一次返回是0。longjmp位于返回的地方,其中val为setjmp第二次返回的值。有个问题是longjmp返回时变量的状态对于是否返回以前状态是不确定的。
二.进程控制
函数
#include<unistd.h>
pid_t getpid(void); //返回进程ID
pid_t getppid(void); //返回父进程ID
uid_t getuid(void); //返回进程的实际用户ID
uid_t getuid(void); //返回有效用户ID
gid_t getgid(void); //返回实际组ID
gid_t getegid(void); //返回进程的有效组ID
fork函数调用后,关于缓冲机制对输出带来的影响需要注意。
fork之后处理文件描述符的常用方法:
(1).父进程等待子进程完成。这种情况下,父进程无需对描述符做任何处理。当子进程终止后,它曾进行过读写操作的任意共享描述符的文件偏移量都进行更新。
(2).父进程和子进程各自执行一段不同的程序段。这种情况下,fork之后,父进程和子进程各自关闭他们不用的文件描述符。这种方法使网络服务进程使用的。
函数vfork创建一个新进程,目的是为了exec一个新程序。他不将父进程的地址空间完全复制到子进程中。且它保证子进程先运行。
#incldue<sys/wait.h>
pid_t wait(int *static);
pid_t waitpid(pid_t pid, int *static,int options);
两个函数返回值:若成功返回进程ID。若出错返回0或者-1
这两个函数区别如下:
1,。在子进程终止前wait阻塞,waitpid选项设置可以不阻塞。
2.waitpid不等待第一个终止子进程,他有若干个选项控制等待进程。static若为NULL不返回状态,否则返回子进程状态
waitpid的pid作用如下:
1.pid==-1 等待任意子进程。此种情况下,waitpid与wait等效。
2.pid>0 等待进程ID与pid相等的子进程。
pid==0 等待组id等于调用进程组id的任意子进程。
pid<-1 等待组ID等于pid绝对值的任意子进程。
函数system
#include<stdlib.h>
int system(const char *cmdstring);
system调用了fork exec waitpid因此有三种返回值
(1)fork失败或者waitpid返回除EINTR之外的出错,则system返回-1,并且设置errno以指示错误类型。
(2)如果exec失败(表示不能执行shell),则其返回值如同shell执行了exit(127)一样。
(3)否则三个函数都返回成功,那么system返回值是shell的终止状态
进程会计
大多数UNIX系统提供了一个选项以进行会计处理。启用该选项后,每当进程结束时内核就写一个会计记录。典型的会计记录包含总量较小的二进制数据,一般包括命令名、所使用的CPU时间总量、用户ID和组ID、启动时间等。
函数(acct)用于启用和禁用进程会计。唯一使用这一函数的命令是accton(8)命令。超级用户(系统管理员)执行一个带路径名参数(如:/var/account/pacct)的accton命令启动会计处理。会计记录写到由带路径名参数指定的文件中,在Linux中,该文件是/var/account/pacct。执行不带任何参数的accton命令可停止会计处理。
会计记录所需的各种数据(如CPU时间、传输的字符数)都由内核保存在进程表中,并在一个新进程被创建时置初值(例如调用fork之后在子进程中)。每次进程终止时都会编写一条会计记录。
会计记录对应于进程而不是程序。在fork之后,内核为子进程初始化一个记录,而不是在一个新程序被执行时做这项工作。虽然exec并不创建一个新的会计记录,但改变了相应记录中的命令名,并且AFORK标志会被清除。这意味着,如果一个进程顺序执行了三个程序(A exec B,然后B exec C,最后C exit),但只会写一条会计记录。该记录中的命令名对应于程序C,但CPU时间是程序A、B、C之和。