做网站如何与美工配合,专有网络WordPress,请拿笔记记下新域名,365建筑人才网进程控制
#xff08;创建、终止#xff0c;等待#xff0c;程序替换#xff09; 进程创建#xff1a; pid_t fork();父子进程#xff0c;数据独有#xff0c;代码共享#xff0c;各有各的地址 pit_t vfork();父进程阻塞#xff0c;直到子进程exit退出或者程序替换之…进程控制
创建、终止等待程序替换 进程创建 pid_t fork();父子进程数据独有代码共享各有各的地址 pit_t vfork();父进程阻塞直到子进程exit退出或者程序替换之后同时运行会出现栈混乱因为它的父子进程是共用地址 显然vfork创建子进程效率更高但是fork在实现写时拷贝技术后效率得到大大提升 写时拷贝技术子进程创建出来后有自己的虚拟地址有自己的页表但是并没有给子进程重新开辟数据的空间进行拷贝而是等到“写时”–这块空间中的数据即将要发生变化时给子进程重新开辟避免了申请空间但子进程不用而造成的效率降低 终止main函数return退出仅限于main因为main是程序的入口函数运行完毕就会退出 坤函数void exit(int retval) 系统调用接口 void _exit(int retval)不刷新缓冲区因为对于系统来说就没有缓冲区这个概念自然就不存在刷新这一说坤函数是有人编写的为了提高io效率而设置有缓冲区 exit(0);return 0;给出的返回值就是进程的返回值 //会创建多少个子进程main进程不算
int main(int argc,char* argv[])
{fork();fork()fork()||fork();fork();
}进程等待父进程创建子进程后等待子进程退出获取退出子进程的退出码释放子进程资源避免僵尸进程。 操作 int wait(int* status) status参数是一个int型空间地址用于向指定空间存放子进程的退出返回值 wait阻塞等待任意一个子进程退出获取返回值释放资源 int waitpid(pid_t pid,int* status,int options) waitpid可以等待任意一个子进程退出或者等待指定的子进程退出并且等待可以阻塞也可以非阻塞。返回值子进程pid 0–没有子进程 出错返回-1 pid 0等待指定pid子进程退出 -1表示任意 options 0–默认阻塞等待 WNOHANG–设置为非阻塞当前没有子进程会立即报错返回 进程的退出码status status总共四个字节实际的退出码保存在低16位的高8位部分进程异常退出信号值保存在低7位 程序替换替换一个进程正在调度管理的程序让一个已有pcb调度管理一个新的程序运行 实现通过exec函数族execlexeclpexecleexecvexecvpexecve将新程序加载到内存中修改当前pcb的页表映射信息初始化虚拟地址空间这时候pcb将调度新的程序运行 阻塞操作简单但是对资源利用率较低 非阻塞操作复杂一些通常要循环操作资源利用率高 在合适的时候采用 #includestdio.h 2 #includeunistd.h3 #includesys/types.h4 #includesys/wait.h5 #includestdlib.h6 int main()7 {8 pid_t retfork();9 if(ret0)10 perror(fork error);11 else if(ret0)12 {13 printf(i am child process;pid:%d ppid:%d\n,getpid(),getppid());14 printf(3秒后退出);15 sleep(3);16 exit(100);//设置退出码为10017 }18 printf(父进程;pid:%d\n,getpid());19 int status0;20 pid_t stwait(status);21 if((status0x7f)0)//异常退出值存在第七位为0表示正常退出!0为异常退出22 printf(等待成功子进程pid%d,状态信息status%d退出码是%d\n,st,status,(status80xff));23 else24 printf(子进程异常退出\n);25 return 0;26 } 程序替换加载一个新的程序到内存中将指定的进程的pcb页表映射信息进行修改让其调度管理新的程序运行。 操作接口 ** int execve(char* path,char* argv[],char* env[]) ** 功能将path这个路径名所指定的程序加载到内存中然后让当前进程调度管理这个程序的运行额而程序运行有可能会有运行参数argv和环境变量env 返回值失败返回-1 替换成功没有返回值因为替换成功就运行新的程序了 #includestdio.h
#includeunistd.h
#includestdlib.h
#includeerrno.h
#includestring.h
int main()
{int a0;a;//execl(/usr/bin/ls,ls,-la,NULL);//可变参数列表要以null结尾//execlp(ls,ls,-lh,NULL);//不需要给path路径但要在PATH中能找到extern char** environ;//execle(/usr/bin/pwd,/usr/bin/pwd,NULL,NULL);//可变参数列表以NULL结尾组织变量设为NULLchar* argv[10]{NULL};argv[0]/usr/bin/tree;//argv[1]NULL;execve(/usr/bin/tree,argv,environ);//系统接口其他都是C语言对系统调用接口的封装printf(%s,strerror(errno));printf(%d\n,a);return 0;
}shell是一个软件命令行解释器捕捉用户的输入了解用户想要什么执行对应的shell指令程序起到用户和内核之间的沟通桥梁
用程序替换实现简单shellminshell这个代码还有许多可升级的地方比如它无法删除如果输入错误那么只能让它出错一次下次重输没有保存之前输入的指令仅仅只是简单通过字符串接收指令通过程序替换执行
#includestdio.h
#includeunistd.h
#includestdlib.h
#includesys/stat.h
#includesys/wait.h
#includestring.h
/** 模拟实现shell运用程序替换* */
int main()
{ while(1){printf(【user%host ~ 】$ );fflush(stdout);char cmd[1024]{0};fgets(cmd,1023,stdin);cmd[strlen(cmd)-1]\0;int argc0;char*argv[32]{NULL};char* ptrcmd;argv[argc]strtok(cmd, );//字符串分割while((argv[argc]strtok(NULL, ))!NULL){argc;}if(strcmp(argv[0],cd)0){chdir(argv[1]);continue;}pid_t child_pidfork();if(child_pid0){perror(fork error);continue;}else if(child_pid0){execvp(argv[0],argv);perror(execvp error);exit(-1);}wait(NULL);}return 0;
}