当前位置: 首页 > news >正文

百度推广登录网址北京seo业务员

百度推广登录网址,北京seo业务员,二手购物网站策划书,福州交通建设投资集团网站目录 一、进程创建 1. fork函数初识 2. fork常规用法 3. fork调用失败的原因 二、进程终止 1. 进程常见的退出方式 #xff08;1#xff09;return 0 #xff08;2#xff09;exit() 退出函数 #xff08;3#xff09;return VS exit() 2. 进程退出场景 三、进…目录 一、进程创建 1. fork函数初识 2. fork常规用法 3. fork调用失败的原因 二、进程终止 1. 进程常见的退出方式 1return 0 2exit() 退出函数  3return VS exit() 2. 进程退出场景 三、进程等待 1. 进程等待的必要性 2. wait()方法 3. waitpid()方法 4. 非阻塞轮询方案 四、程序替换 1. 替换原理 2.替换函数 正文 一、进程创建 1. fork函数初识 在linux中fork函数是非常重要的函数它从已存在进程中创建⼀个新进程。新进程为子进程而原进程为⽗进程。要创建子进程必须通过fork创建 # include unistd.h pid_t fork ( void ); 返回值子进程中返回 0 父进程返回子进程 id 出错返回 -1 进程调用fork内核做三步走 1分配新的内存块和内核数据结构给子进程 2将父进程部分数据结构内容拷贝至子进程 3更改映射关系 fork返回开始调度器调度  fork创建进程是一种写时拷贝。 进程在加载到内存时OS通过先描述后组织的方法管理进程进程会有PCB、虚拟地址空间、页表。fork后的子进程除了拷贝父进程的PCB、虚拟地址空间、页表外还要管理页表中的权限读/写。 fork之前父进程页表项权限是可读写fork后由于写时复制机制COW的原因内核可能会将可写页标记为只读即使父进程原本是可写的以启用 COW。所以当进程尝试写入操作系统“报错”OS对错误分为两类1.真错杀死进程2 .写入错误进行内核三步走在第三步更改映射关系时把全部权限由只读改为可读写。 1.1 写时复制COW 为了优化性能Linux 会标记可写页为 COW。此时 父子进程的页表项会被改为 只读即使原来是可写的。 当任一进程尝试写入该页时会触发 缺页异常Page Fault内核会复制该页并恢复可写权限。 大家是否疑惑为什么不直接拷贝父进程把父子数据分开呢 其实fork创建子进程后并不是什么数据都用如果父进程数据量大在子进程用不到的情况下会造成内存空间的占用所以才有了写时拷贝也称为惰性申请当你需要再给你拷一份。 2. fork常规用法 ⼀个⽗进程希望复制自己使父子进程同时执⾏不同的代码段。例如父进程等待客户端请求生成子进程来处理请求。 ⼀个进程要执行⼀个不同的程序。例如子进程从fork返回后调用exec函数。 3. fork调用失败的原因 系统中有太多的进程 实际用户的进程数超过了限制 二、进程终止 进程终止的本质是释放系统资源就是释放进程申请的相关内核数据结构和对应的数据和代码。 1. 进程常见的退出方式 正常终⽌可以通过 echo $? 查看进程退出码 1. 从main返回 2. 调⽤exit 3. _exit 异常退出 ctrl c信号终⽌ 1return 0 return 0 表示退出时的退出码 可以告诉我们最后⼀次执⾏的命令的状态。在命令结束以后我们可以知道命令是成功完成的还是以错误结束的。其基本思想是程序返回退出代码 0 时表⽰执⾏成功没有问题。代码 1 或 0 以外的任何代码都被视为不成功。   Linux Shell 中的主要退出码 而返回的退出码会被操作系统或得用来知道任务执行情况和错误对应原因情况。 可通过指令: echo $?        获得最近一个进程执行完的退出码  2exit() 退出函数  除了return 0 这种常见的退出方式外还有个exit函数。它的底层调用系统的_exit()函数与直接调用_exit() 函数的区别在于exit() 函数会将数据刷到内存缓冲区而_exit() 直接结束退出。 3return VS exit() 1. return 表示退出当前函数exit()表示立即终止整个程序 2. exit()可以在程序的任意位置调用 2. 进程退出场景 1. 代码运⾏完毕结果正确 2. 代码运⾏完毕结果不正确 3. 代码没运行完毕进程异常 其中代码异常终止了退出码本身就无意义当进程异常时OS知道后会自动杀掉进程。 三、进程等待 1. 进程等待的必要性 之前讲过⼦进程退出⽗进程如果不管不顾就可能造成‘僵⼫进程’的问题进⽽造成内存 泄漏。 另外进程⼀旦变成僵⼫状态那就⼑枪不⼊“杀⼈不眨眼”的kill -9 也⽆能为⼒因为谁也 没有办法杀死⼀个已经死去的进程。 最后⽗进程派给⼦进程的任务完成的如何我们需要知道。如⼦进程运⾏完成结果对还是不对或者是否正常退出。 ⽗进程通过进程等待的⽅式回收⼦进程资源获取⼦进程退出信息 之前在进程状态那篇文章讲过如果子进程要想结束必须由父进程回收不然子进程会呈现僵尸状态。 进程等待是让父进程通过等待的方式回收子进程PCB如果需要会获取到子进程的退出信息。 2. wait()方法 # include sys/types.h # include sys/wait.h pid_t wait ( int * status); 返回值 成功返回被等待进程 pid 失败返回 -1 。 参数 输出型参数获取⼦进程退出状态 , 不关⼼则可以设置成为 NULL 父进程调用wait表示父进程等待任意一个子进程。如果子进程没有退出父进程wait时会阻塞如果子进程退出父进程wait时会返回子进程pid让系统自动解决子进程的僵尸问题 以下通过代码验证wait()真的回收多个子进程 为了让大家看到子进程真会等待wait回收所以故意让父进程休眠5秒后再进行回收在等待时子进程全部呈现僵尸状态。 执行以上代码后通过指令while :; do ps ajx | grep test ps ajx | head -1; sleep 1 ; done;可查询进程状态如下 父进程等待成功回收后不存在子进程说明调用wait()方法是可以等待子进程进行PCB回收的 3. waitpid()方法 相比于wait()这是最佳等待方法 pid_ t waitpid ( pid_t pid, int *status, int options); 返回值 当正常返回的时候 waitpid 返回收集到的⼦进程的进程 ID 如果设置了选项 WNOHANG, ⽽调⽤中 waitpid 发现没有已退出的⼦进程可收集 , 则返回 0 如果调⽤中出错 , 则返回 -1 , 这时 errno 会被设置成相应的值以指⽰错误所在 参数 pid Pid-1 , 等待任⼀个⼦进程。与 wait 等效。 Pid0. 等待其进程 ID 与 pid 相等的⼦进程。 status: 输出型参数 宏形式获取 WIFEXITED(status): 若为正常终⽌⼦进程返回的状态则为真。查看进程是 否是正常退出 WEXITSTATUS(status): 若 WIFEXITED非 零提取⼦进程退出码。查看进程的 退出码 options: 默认为 0 表示阻塞等待 WNOHANG: 若 pid 指定的⼦进程没有结束则 waitpid() 函数返回 0 不予以等 待。若正常结束则返回该⼦进程的 ID 。 进程退出的场景有三种形式 1.代码运行完毕结果正确 2.代码运行完毕结果错误 3.代码异常结果无异议 我们如何知道进程退出对应哪一种情况呢就是通过进程结束后返回的退出码和退出信息在Linux中可通过命令kill -l进行查看所有退出码 可以发现这些数字是从1开始没有0号数字因为每个数字后面对应的是导致错误的原因0代表的是程序正常结束结果正确这也是为什么main函数中我们return的是0。 代码正常结束退出码为0退出信号也为0所以我们实际上是用两个数来表示子进程执行情况而这两个数最终会合并为一个数放在status中带出让用户看到 1.进程退出码 --status8 0xFF 2.进程退出信号 -- status 0x7F 当子进程退出呈现僵尸状态退出信息会写入到子进程PCB中父进程通过waitpid()方法获取子进程内属性数据然后再让OS释放目标PCB 。僵尸状态不能释放是因为数据还没被父进程拿到。 以下是waitpid()方法阻塞等待每一个指定进程 利用宏WIFEXITED(status)和WEXITSTATUS(status)简化代码 4. 非阻塞轮询方案 上面提到的waitpid都是阻塞式等待子进程也就是返回值要么等待成功要么等待失败。 非阻塞等待只等待一次还没结束父进程退出直接返回0。它的返回值不再是两个而是三个 子进程没退  等待成功是指你等的子进程存在但是还没运行结束这时返回0 1. 子进程退出 等待成功 -- 返回值0 2. 子进程没退  等待成功 -- 返回值0 3. 等待失败不是你的子进程--返回值0 非阻塞等待写法  非阻塞轮询等待就是手动加一个循环重复等待直到子进程运行结束为止。 为什么要非阻塞轮询它的效率为什么高 非阻塞时父进程只等待一次没等到直接退出会导致还在运行的子进程成为孤儿进程被bash托管这样就不在与显示器终端关联CtrlC无法终结只能用kill命令杀死所以用非阻塞轮询。 非阻塞轮询不会因为条件没就绪就阻塞当子进程还没运行完父进程可以去做其他事提高了效率 四、程序替换 fork()创建一个子进程后子进程1执行父进程的一部分代码和数据2执行一个全新的程序有自己的代码和数据是一个真正独立的进程写时拷贝 1. 替换原理 ⽤fork创建子进程后执行的是和⽗进程相同的程序(但有可能执行不同的代码分⽀),⼦进程往往要调用一种exec函数以执行另⼀个程序。当进程调用⼀种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。 2.替换函数 其实有六种以exec开头的函数,统称exec函数 # include unistd.h 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 execve ( const char *path, char * const argv[], char * const envp[]); 这些函数如果调⽤成功则加载新的程序从启动代码开始执行,不再返回。 如果调用出错则返回-1 所以exec函数只有出错的返回值而没有成功的返回值。 以下是父进程创建一个子进程后让其执行程序替换的代码实现 上面代码执行execl后不再执行printf因为替换成功进程执行了ls的代码就不会执行后续代码而替换失败则返回-1只要返回必是失败 程序替换一般都是让子进程执行例如我们双击桌面一个图标实际上在双击时创建了子进程通过写时拷贝再让其程序替换成用户要执行操作的对应代码。 完~感谢观看
http://www.hkea.cn/news/14284945/

相关文章:

  • 什么是网站内链官网优化 报价
  • 重庆网站建设网页设计广告
  • 网站建设项目单子来源wordpress泛域名插件
  • 深圳市住房和城乡建设厅网站首页有什么网站做悬赏的 能挣钱
  • 汽车网站首页模板代码重庆seo网站排名优化
  • 快站微信网站制作东大桥做网站的公司
  • 如何快速建立网站个人网站开发的感想
  • 校园网站建设情况说明做商城的网站程序
  • 网站建设公司一般多少钱wordpress 的模板
  • 做网站卖产品投资大嘛网站的功能和作用
  • 兰溪优秀高端网站设计地址宝安做网站的公司
  • 论医院网站的建设丰泽区住房和城乡建设局投诉网站
  • 网站seo诊断优化方案撰写网络推广策划案
  • 手机网站建站APP网站建设新闻咨询
  • 简单 手机 网站 源码网页制作属于哪个专业
  • 开办 网站建设费 科目郴房网
  • 阿里买域名 电脑做网站wordpress自动回到顶部
  • 网站安全建设模板wordpress 文章自定义
  • 佛山 网站开发wordpress环境需求
  • 广州口碑好的网站建设定制广告案例的网站
  • flashfxp 网站网站开发属于计算机系统开发吗
  • 网站制作公司 佛山策划一个网站
  • 做网站导出用什么色彩模式免费十大软件app
  • 做网站内容来源网站的前端和后端
  • 程序员招聘求职的网站坐什么网站能用到html5
  • 做网站侵权吗wordpress 插件商城
  • 什么网站可以做TCGA病理分期专业外贸制作网站
  • 云南建设厅官方网站免费加盟无需店面
  • 自己给网站做logo代理服务器地址列表
  • 网站建设视频教程。网站建设模块方案