8.exec族函数和system函数
8.1exec族函数
- exec族函数可以直接加载运行一个编译好的可执行程序。
- 典型的多进程任务并不是直接在子进程的if中写入新程序的代码。而是使用exec族运行新的可执行程序。
exec族的6个函数:
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg,
.../* (char *) NULL */);
int execv(const char *path, char *const argv[]);
int execlp(const char *file, const char *arg,
.../* (char *) NULL */);
int execvp(const char *file, char *const argv[]);
int execle(const char *path, const char *arg,
.../*, (char *) NULL, char * const envp[] */);
int execvpe(const char *file, char *const argv[],char *const envp[]);
- execl和execv 的区别是传参的格式不同。execl是把参数列表(多个字符串,必须以NULL结尾)依次排列而成,execv是把参数列表事先放入一个字符串数组中,再把这个字符串数组传给execv函数。
- execlp和execvp 较上面2个的区别是:上面2个执行程序时必须指定可执行程序的全路径,如果没有找到path这个文件则直接报错。而这两个函数传递的可以是file,也可以是path。这两个函数会首先去找file,如果找到则直接执行,如果没找到则会继续到环境变量PATH所指定的目录下找,如果找到则执行如果没找到则报错。
- execle和execvpe 这两个函数的参数列表中多了一个字符串数组envp形参,e就是environment环境变量的意思,和基本exec的区别就是:执行可执行程序时会多传一个环境变量的字符串数组给待执行的程序。
8.2system函数
system用来执行一个shell命令。system 内部实现其实就是 fork + exec,区别是system是一个原子操作(整个操作一旦开始就会不被打断的执行完。原子操作的好处就是不会引来竞争状态,坏处是自己单独连续占用CPU时间太长影响系统整体实时性,因此应该尽量避免不必要的原子操作,就算不得不原子操作也应该尽量原子操作的时间缩短。)
#include <stdlib.h>
int system(const char *command);
9.进程状态和进程关系
9.1进程状态
进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。
- 运行(running)态:进程占有处理器正在运行。
- 就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。
- 等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。
9.2进程关系
- 无关系:两个进程没有任何关系。
- 父子进程关系:两个进程是父子进程关系。
- 进程组(由若干进程构成一个进程组):两个进程属于同一进程组。
- 会话(进程组的组):两个进程属于同一会话组。
10.守护进程
守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。
- 服务器程序就是一个一直在运行的程序,可以提供某种服务(例如nfs服务器提供nfs通信方式),当需要这种服务时可以调用服务器程序(和服务器程序通信以得到服务器程序的帮助)。服务器程序一般都实现为守护进程。
- 任何一个进程都可以实现成守护进程.