unistd.h
pid_t getpid(void); \\返回当前进程标识PID
pid_t getppid(void); \\返回父进程标识PPID
pid_t fork(); \\产生一个新的进程,称为子进程,成功返回子进程id,向子进程返回0,失败向原进程返回-1
vfork 借用而不复制父进程空间
exec族函数:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,… , const char *envp[]);
int execv(const char *path, const char *argv[]);
int execvp(const char *file, const char *argv[]);
int execve(const char *path, const char *argv[], const char *envp[]);
path/file:可执行文件名
arg/argv:传给path/file可执行文件的命令行参数
envp:环境变量
l希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志
v希望接收到一个以NULL结尾的字符串数组的指针
p是一个以NULL结尾的字符串数组指针
e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境
成功则没有返回值(因为替换),失败返回-1
孤儿进程
父进程在子进程未执行完就终止,子进程沦为孤儿进程,并立刻被init进程收养为子进程。
僵死进程
子进程先终止,但父进程忽略SIGCHLD信号或无暇调用wait处理子进程,则子进程沦为僵死进程。
僵死进程无法用命令无法直接消除,方法
(1)父进程在合适的时机调用wait,直接消除
(2)杀死父进程,僵死->孤儿->init收养,从而消除
危害:占用进程号
wait:
sys/types.h
sys/wait.h
pid_t wait(int*); \\阻塞自己,直到找到一个已退出的子进程,收集这个子进程的信息,将其彻底销毁,参数用来保存子进程退出时的一些信息,成功返回子进程ID,失败返回-1
pid_t waitpid(pid_t pid, int *, int options);
pid>0: 只等待ID为pid的子进程,不管其它子进程
pid=-1:等待任何一个子进程退出,此时和wait作用一样
pid=0:扥带同一个进程组中的任何子进程,如果子进程已经加入别的进程组,则不会对其理睬
pid<-1:等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值
options:options提供了一些额外的选项来控制waitpid,如果设为WNOHANG,则即使没有子进程退出,也会继续执行下去,不会像wait那样一直等待
exit:
stdlib.h
void exit(int);
unistd.h
void _exit(int);
都无返回值
区别:exit在关闭文件时会刷新缓冲区,_exit不会;exit可以不带终止状态,_exit必须带
system:
stdlib.h
int system(const char *string); \\在一个进程中运行另一个程序,失败返回-1
实际上是通过fork,exec,waitpid实现的
例:system("ls -l ./1.txt");