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

个人备案的网站可以做什么电子商务网站开发实践

个人备案的网站可以做什么,电子商务网站开发实践,淄博网站建设网宽,海安建设局网站本篇文章主要讲述的是进程的退出和进程等待。希望本篇文章的内容会对你有所帮助。 文章目录 一、fork创建子进程 1、1 在创建子进程中操作系统的作用 1、2 写时拷贝 二、进程终止 2、1 常见的进程退出 2、2 进程的退出码 2、2、1 运行结果正确实例 2、2、2 运行结果不正确实例…   本篇文章主要讲述的是进程的退出和进程等待。希望本篇文章的内容会对你有所帮助。 文章目录 一、fork创建子进程 1、1 在创建子进程中操作系统的作用 1、2 写时拷贝 二、进程终止 2、1 常见的进程退出 2、2 进程的退出码 2、2、1 运行结果正确实例  2、2、2 运行结果不正确实例 2、2、3 代码运行异常 2、3 常见的进程退出方式 三、进程等待 3、1 进程等待的引入 3、2 等待的方法 3、2、1 wait 方法 3、2、2 waitpid 方法 四、总结 ‍♂️ 作者Ggggggtm ‍♂️  专栏Linux从入门到精通   标题进程控制  ❣️ 寄语与其忙着诉苦不如低头赶路奋路前行终将遇到一番好风景 ❣️   一、fork创建子进程 我们知道fork是创建子进程的。创建的子进程在我们不做任何操作的情况下子进程有数据和代码吗操作系统都做了哪些事情呢 1、1 在创建子进程中操作系统的作用 我们先想一下创建一个子进程本质上在是干啥是不是系统中多了一个进程呢进程是由所对应的代码和数据再加上内核数据结构构成的。 那一切都就很容易理解了。创建子进程就是给子进程分配自己的内核数据结构。同时把部分所需代码和数据加载到进程当中。我们父进程的代码和数据一般都是从磁盘加载我们自己所写的代码过来的。子进程的代码和数据哪里来的呢   因为在加载的过程中子进程并没有自己的代码和数据所以子进程只能使用父进程的代码和数据了也就是子进程和父进程共享一份数据   我们知道每个进程都是具有独立性的进程之间不会相互影响。那子进程和父进程共享一份代码和数据不管是子进程还是父进程去修改数据那不就影响到了另一个进程吗因为代码和数据是共享的。但是事实并不是不会相互影响。呢么做到的不相互影响呢   我们为了保持进程的独立性就采用了写时拷贝技术。那么我们接下来先了解一下写时拷贝技术。 1、2 写时拷贝 我们知道子进程和父进程共享一份代码和数据那么只要有任何一进程对其数据进行修改就会对该数据进行深拷贝再进行修改。这就很好的解决了相互影响的问题。这就是写时拷贝只有在对其数据进行修改时才对数据开空间进行深拷贝。   写时拷贝就是一种拖延技术是在浅拷贝的基础之上增加了引用计数的方式来实现的。   引用计数用来记录资源使用者的个数。在构造时将资源的计数给成1每增加一个对象使用该资源就给计数增加1当某个对象被销毁时先给该计数减1然后再检查是否需要释放资源如果计数为1说明该对象时资源的最后一个使用者将该资源释放否则就不能释放因为还有其他对象在使用该资源。 那么这里有一个问题为什么在创建子进程时不直接对数据进行深拷贝,而是采用与父进程共享一份代码和数据呢   首先我们所创建的子进程可能就不会用到数据空间即使用到了也可能是只读并不会对其进行修改而影响到进程的独立性。其次操作系统也无法预知那些空间会被写入。所以操作系统选择写时拷贝技术会有以下好处 可以很好的分离父子进程的数据保证进程的独立性用时才分配空间合理充分利用了内存是高效使用内存的一种表现。 二、进程终止 2、1 常见的进程退出 我们常见的进程退出有如下三种 代码运行完毕结果正确 代码运行完毕结果不正确 代码异常终止。 关键是我们怎么知道进程运行结果正确还是不正确呢这时候就需要了解一下 进程的退出码了。 2、2 进程的退出码 进程的退出码Exit Code是一个整数值用于表示进程在终止时返回给操作系统的状态信息。退出码提供了有关进程是否成功执行和执行结果的信息。如果出错同时也方便我们地位错误的原因。 2、2、1 运行结果正确实例  我们平常写代码中也一直在用到退出码——return 0。在main函数中return 的返回值就算是进程的退出码。我们可在linux下查看一下。linux下查看最近进程的退出码的命令是echo $?。实例代码如下 #includeiostream using namespace std; int main() { cout正常运行endl; return 0; }   我们再来查看一下改进程的退出码结果如下   那要是我们设置 return 的返回值为100呢我们再来看看结果 2、2、2 运行结果不正确实例 我们可通过一个判断来完成结果是否正确。代码如下 int main() { const int N100; int ret0; for(int i0;iN;i) { reti; } if(ret!5050) return 1; return 0; }   我们知道1到100的和为5050。我们在这里故意把答案写错来判断一下结果如下    运行结果不正确的原因有很多我们可通过sterror函数将它们打印出来结果如下    我们发现一共是由133种运行错误的结果。我们不妨来验证一下   退出码是2是不是与我们刚刚打印出的对上了  2、2、3 代码运行异常 我们先看如下代码 int main() {couthello linuxendl;couthello linuxendl; couthello linuxendl; int* pNULL;*p1;couthello linuxendl;couthello linuxendl;couthello linuxendl;return 0; }上述代码是对空指针进行了访问并且修改必然会导致程序崩溃。结果如下:     我们看到Segmentation fault。我们再看退出码是139。当程序崩溃时退出码毫无意义并且一般情况下 return 语句都不会别执行 2、3 常见的进程退出方式 我们平常再写代码的时候如何用代码终止一个进程呢其实在main() 函数中的return语句就是终止进程的。return 的值就是退出码返回给操作系统。那还有其他的方式吗答案是有的。我们接着往下看。 可能我们大家在平常中也会用到exit函数。exit在代码的任何地方调用都是表示终止进程。那我们来简单测试一下exit函数。代码如下 #includestdio.h #includestdlib.h #includeunistd.h int main() { printf(hello linux); sleep(3); exit(111); return 0; }   我们上面打印的字符串并没有选择通过 \n 或者fflush 将其在缓冲区刷新出来而是休眠了3秒。那当exit 终止程序时会将其刷新出来吗我们看如下运行结果   通过上述发现在exit 终止程序是会刷新缓冲区。退出码也是我们所设置的 111 。  其实还有一个函数_exit() 也是用来终止程序的。我们不妨也来简单测试一下 _exit() 函数看是否与 exit() 函数相同。代码如下 #includestdio.h #includestdlib.h #includeunistd.h int main() { printf(hello linux); sleep(3); _exit(111); return 0; }   运行结果如下   我们发现_exit() 函数并没有刷新缓冲区   exit() 函数时C语言的库函数_exit() 是系统的接口。其实exit() 底层也是调用的_exit()但是在调用_exit() 之前还做了一些其他的工作  执行用户通过 atexit或on_exit定义的清理函数。 关闭所有打开的流所有的缓存数据均被写入。 调用_exit。 那么提问printf 所打印的数据并不是直接向输出设备输出而是保存在了缓冲区。那么这个缓冲区是在哪里呢是由谁来维护的呢   我们先看如下图片   _exit() 函数直接调的是操作系统內部的函数。如果上述的缓冲区是在操作系统內部的话_exit() 函数也会把数据刷新出来。但是是并没有。从这点也可以说明上述的缓冲区并不是在操作系统內部。显而易见缓冲区是由C语言标准库函数来维护的。 这里对exit 和 _exit函数进行总结。exit()和_exit()都是用于退出程序的函数但在使用方式和功能上存在一些区别。   exit()是C语言标准库中的函数在C中也可以使用。它执行以下操作 调用终止处理程序atexit函数注册的函数。刷新并关闭stdin、stdout和stderr流。调用各个注册函数进行清理工作。通过调用C库实现的_exit()系统调用来终止进程。   _exit()是一个系统调用用于直接终止进程不会进行任何清理工作。它执行以下操作 立即终止进程并不执行后续的清理工作。不会刷新缓冲区或关闭文件描述符也不会执行终止处理程序。可以带有一个整数参数表示退出状态将该值传递给操作系统。   因此exit()更安全它可以确保执行所有的清理工作并且允许某些回调函数得到执行的机会。_exit()则是一种粗暴的退出方式立即终止进程没有机会执行任何清理工作。 三、进程等待 3、1 进程等待的引入 在进程的状态中讲到中讲到子进程退出父进程如果不管不顾就可能造成‘僵尸进程’的问题进而造成内存泄漏。 另外进程一旦变成僵尸状态那就刀枪不入“杀人不眨眼”的kill -9 也无能为力因为谁也没有办法杀死一个已经死去的进程。   最后父进程派给子进程的任务完成的如何我们需要知道。如子进程运行完成结果对还是不对 或者是否正常退出。那么父进程怎么获取这些信息呢   父进程通过进程等待的方式回收子进程资源获取子进程退出信息。这也是父进程等待的原因那父进程是如何等待的呢 3、2 等待的方法 3、2、1 wait 方法 进程等待函数wait()是在操作系统中用于等待子进程结束并获取子进程的状态信息的函数。wait()函数用于等待任意一个子进程终止并可以获取子进程的终止状态。我们再来看一下wait的使用方法   上图我们可到使用wait需要引入的头文件。同时wait的返回值 成功返回被等待进程pid失败返回-1参数 输出型参数获取子进程退出状态,不关心则可以设置成为NULL。   在下面讲述waitpid函数时会讲到status。我们再来看wait的使用方法。代码如下 #includestdio.h #includestdlib.h #includeunistd.h #includesys/types.h #includesys/wait.hint main() {pid_t id fork();if(id 0){perror(fork);exit(1); //标识进程运行完毕结果不正确}else if(id 0) { //子进程 int cnt 5; while(cnt) { printf(cnt: %d, 我是子进程, pid: %d, ppid : %d\n, cnt--, getpid(), getppid()); sleep(1);}exit(0); } else { //父进程printf(我是父进程, pid: %d, ppid: %d\n, getpid(), getppid());pid_t retwait(NULL);if(ret0){printf(等待成功,%d\n,ret);}}return 0; }运行结果如下   观察上图发现父进程打印出第一句话后就不再往后执行。没错wait就是阻塞式等待。就是当子进程退出时wait回收子进程的资源和退出信息。当子进程一直在运行不退出wait就一直处于阻塞状态进行等待。 我们不妨来验证一下wait到底回收子进程的资源了吗。验证的代码如上述验证wait的代码几乎一样只不过是当wait等待成功后不让父进程退出接着打印。我们看如下运行结果   通过上图我们看到当子进程推出后父进程仍然在打印并没有退出。如果父进程不对子进程进行回收子进程就会进入僵尸状态。我们在查看的时候子进程并没有进入僵尸状态而是被回收了。 我们接下来再看一下waitpid的使用方法。 3、2、2 waitpid 方法 waitpid()函数用于等待指定进程ID的子进程终止也可等待任意子进程的终止。我们先来看看怎么使用waitpid。如下图   返回值 当正常返回的时候waitpid 返回收集到的子进程的进程 ID 如果设置了选项WNOHANG, 而调用中 waitpid 发现没有已退出的子进程可收集 , 则返回 0 如果调用中出错, 则返回 -1, 这时 errno 会被设置成相应的值以指示错误所在 参数 pid pid-1,等待任一个子进程与wait等效。 Pid0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码 options: WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进程的ID。0表示阻塞式等待。 获取子进程status的方式 wait 和 waitpid 都有一个 status 参数该参数是一个输出型参数由操作系统填充。如果传递NULL 表示不关心子进程的退出状态信息。 否则操作系统会根据该参数将子进程的退出信息反馈给父进程。 status 不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究 status 低 16 比特位 我们结合代码一起理解一下waitpid和  获取子进程status。代码如下 #include stdio.h #include unistd.h #include string.h #include stdlib.h #include sys/types.h #include sys/wait.hint code 0;int main() {pid_t id fork();if(id 0){perror(fork);exit(1); //标识进程运行完毕结果不正确} else if(id 0) { //子进程 int cnt 5; while(cnt--) { printf(cnt: %d, 我是子进程, pid: %d, ppid : %d\n, cnt, getpid(), getppid()); sleep(1); } exit(0); }else{//父进程printf(我是父进程, pid: %d, ppid: %d\n, getpid(), getppid());int status 0; pid_t ret waitpid(id, status, 0); //阻塞式的等待if(ret 0){// 0x7F - 0000.000 111 1111printf(等待子进程成功, ret: %d, 子进程收到的信号编号: %d,子进程退出码: %d\n,\ret, status 0x7F ,(status 8)0xFF); //0xff -- 0000...000 1111 1111}} }运行结果如下 父进程也可通过如下方式看子进程是否正常终止和获取子进程的退出码 if(WIFEXITED(status)) //是否正常终止子进程{//子进程是正常退出的printf(子进程执行完毕,子进程的退出码: %d\n, WEXITSTATUS(status)); //获取退出码}else{printf(子进程异常退出: %d\n, WIFEXITED(status));}我们再来看一下waitpid进行非阻塞等待。 第三个参数就是WNOHANG。我们知道Linux使用C语言写的waitpid是系统调用接口也就是操作系统调用自己内部的函数。这个函数就是用C语言写的函数全部是大写的WNOHANG是什么呢宏定义WNOHANG的值就是1为什么不直接写1呢因为可能过一段时间我们就不知道1在这里是什么意思了这类数字也被称为魔鬼数字/魔术数字。WNOHANG是Wait No HANG。也就是没有夯住。夯住通常指的是一个进程或者应用程序无法继续正常执行似乎被卡住了或者不再响应用户的输入或命令。这种情况也被称为进程僵死或进程挂起。 我们通过如下代码测试一下非阻塞等待 #includesys/wait.h #includesys/types.h #includestdlib.h #includeunistd.h #includestdio.htypedef void (*handler_t)(); //函数指针类型std::vectorhandler_t handlers; //函数指针数组void fun_one() {printf(这是一个临时任务1\n); } void fun_two() {printf(这是一个临时任务2\n); }// 设置对应的方法回调 // 以后想让父进程闲了执行任何方法的时候只要向Load里面注册就可以让父进程执行对应的方法喽! void Load() {handlers.push_back(fun_one);handlers.push_back(fun_two); }int main() {pid_t id fork();if(id 0){// 子进程int cnt 5;while(cnt){printf(我是子进程: %d\n, cnt--);sleep(1);}exit(11); // 11 仅仅用来测试}else{int quit 0; while(!quit){int status 0;pid_t res waitpid(-1, status, WNOHANG); //以非阻塞方式等待if(res 0){ //等待成功 子进程退出 printf(等待子进程退出成功, 退出码: %d\n, WEXITSTATUS(status)); quit 1; } else if( res 0 ) { //等待成功 但子进程并未退出 printf(子进程还在运行中暂时还没有退出父进程可以在等一等, 处理一下其他事情\n); if(handlers.empty()) Load(); for(auto iter : handlers) { //执行处理其他任务 iter(); } } else { //等待失败 printf(wait失败!\n); quit 1; } sleep(1); } } return 0; }   waitpid函数不管子进程是否运行结束都会有一个返回值。返回值大于0等待成功 且 子进程退出。返回值等于0等待成功 且 子进程没有退出。返回值小于0等待失败。当我们知道子进程并没投退出时父进程还可做一些其他事情直到子进程退出。我们看运行结果   从上述的运行结果中可看出在子进程没有退出的情况下父进程也可做一些其他事情。退出码为11是我们自己设置的。  四、总结 子进程的退出状态信息返回给了操作系统中的进程控制块内为什么wait和waitpid能够拿到子进程的退出状态呢wait和waitpid是系统调用接口 就是操作系统內部的函数当然可以拿到了。设置全局变量行吗答案是不行的。一旦对全局变量修改就会发生写时拷贝。同时信号也无法处理。   由于内容较多分为两篇文章来整理。本篇文章主要讲述的是进程的退出和进程等待下篇文章会讲到进程的替换。感谢阅读ovo~
http://www.zqtcl.cn/news/766422/

相关文章:

  • 重庆定制网站建设公司郑州网站模板
  • 网站 建设 领导小组wordpress下拉 友情链接
  • 做网站用php广州最新新闻
  • 福州市住房和城乡建设局网站18款禁用观看黄入口
  • 西安网站制作工作室网页怎么做成网站
  • 做h5网站公司百度知道网页入口
  • 网站建设 中企动力上海在线设计房屋效果图
  • 河南宝盈建设集团有限公司网站代理二级分销系统
  • 青岛高级网站建设价格对外宣传及网站建设文件稿
  • 网络营销中自建网站建设局是干嘛的单位
  • 做网站的公司 贵阳流媒体网站建设
  • 北京建网站重庆安全建设工程信息网
  • 做公司网站的尺寸一般是多大无障碍浏览网站怎么做
  • 网站登陆界面psd手机一元云购网站建设
  • 网站规范化建设wordpress iis7.5 伪静态
  • 济南网站设计建设公司深圳seo外包公司
  • 重庆信息网站推广网站做推广如何设计二维码
  • 学历低的人不适合学编程小红书seo关键词优化多少钱
  • pc网站制作公司企业邮箱格式模板
  • 河南5G网站基站建设信息wordpress自定义文章页面模板下载
  • 宁波三优互动网站建设公司怎么样手机app商城
  • 散热器 东莞网站建设php模板源码
  • 怎么申请域名建网站凡科网站建设总结
  • 温州网站设计定制外贸人才网哪家最好
  • 永康门业微网站建设做一个网站要多长时间
  • 南山网站建设哪家好四川省微信网站建设公
  • 网件路由器做网站网站建设中 提示
  • 全运网站的建设徐州网络推广公司排名
  • 成品网站源码1688体验区南宁网络推广服务商
  • 广州品牌网站开发公司网站建设价位