进程创建
fork函数
fork()->复制,返回值,写时拷贝
vfork()-> 创建子进程与父进程共用同一块虚拟地址空间,为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出,或者进行程序替换。
进程退出
进程退出的场景
正常退出:结果符合预期
正常退出:结果不符合预期
异常退出:
终止方式
main函数中的return; exit(int statu) _exit(int statu)
exit库函数:退出时刷新缓冲区
_exit系统调用接口:退出时,不会刷新缓冲区,直接释放资源;
#include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 int main(){
7 int i=0;
8 for(i=0;i<256;++i){
9 //char *streror(int errrnum);
10 //通过错误编号会获取错误描述信息
11 printf("error :%s\n",strerror(i));
12 //perror("error");
13 }
14 int pid=fork();
15 if(pid<0){
16 //每次调用系统调用接口,不管对错都会重置errno全局变量
17 perror("fork error");
E> 18 printf("fork error :%s\n",strerror(errno));
19 }
20
21 printf("hello");
22 sleep(3);
23
24 _exit(199);
25 //void exit(int status);
26 //exit(255);
27
28 //return(243);
29 }
进程等待:
进程等待:等待子进程的退出—为了避免僵尸进程;
pid_ t wait(int status)----阻塞等待任意一个子进程退出
阻塞:发起一个系统调用完成功能,当前如果不具备完成条件;则等待直到完成功能后返回;
非阻塞:当前如果不具备完成条件,则立即报错返回;
1 进程等待
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5
6 int main(){
7 int pid=fork();
8 if(pid<0){
9 perror("fork error");
10 exit(-1);
11 }
12 else if(pid==0){
13 sleep(5);
14 exit(0);
15 }
16 //pid_t wait(int *status);
17 //阻塞等待任意一个子进程退出,如果当前没有子进程退出,则一直等待
18 //status: 用于获取子进程的推出码,不关注则置空即可
19 //返回值:推出的子进程的pid
//pid_t waitpid(pid_t pid, int *status, int options);
//可以等待任意一个子进程的退出/等待指定子进程退出
//pid: -1 等待任意一个子进程
//pid: >0 等待指定子进程
//status 用于获取子进程的退出码;不关注则置空;
//options:
0 阻塞等待子进程退出
WNOHANG 将waitpid 设置为feizuse
//返回值:
>0 退出子进程的pid
=0 当前没有子进程退出
<0 出错
// int ret = waitpid(pid,NULL,0);
20 wait(NULL);
21 while(1){
22 printf("----i am parent\n");
23 sleep(2);
24 }
25 return 0;
26 }
程序代换
替换一个进程所正在运行的程序—重新加载其他程序到内存,重新映射进程虚拟地址空间与内存映射位置到新的程序地址上;(代码段修改映射位置,数据段重新初始化)
进程重新从main函数开始调度运行
如何进行程序替换
exec函数族:
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,
..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
execl
execlp
execle
execlv
execvp
esecve
l和v的区别:传参的区别
l是程序运行参数使用函数的实参平铺的形式赋予,execl(ls ,-l -a ,NULL)
v 是程序运行参数使用字符串指针数组赋予,argv[0]=ls arfv[1]=-l execl(ls , argv);
带p和不带p的区别:
带p:程序名称可以不带路径,直接去PATH环境变量所指定的路径下找程序, execlp(ls…)
不带p:程序名称必须带路径 execl(/bin/ls/…)
带e和不带e的区别:
带e:给进程自定义环境变量 env[0]=“myenv = 100” execl(ls ,… ,NULL ,env)
不带e:继承原有默认的环境变量 execl(ls ,…0;