#bsPanelHolder,#sinaads_pdps54771{display:none;}a.bsSiteLink{text-decoration:none;color:#666;}a.bsSiteLink:hover{text-decoration:underline;}a.bshareDiv{overflow:hidden;height:16px;line-height:18px;font-size:14px;color:#333;padding-left:0;}a.bshareDiv:hover{text-decoration:none;}div.bsTitle{padding:0 8px;border-bottom:1px solid #e8e8e8;color:#666;background:#f2f2f2;text-align:left;}div.buzzButton{cursor:pointer;}div.bsRlogo,div.bsRlogoSel{width:68px;float:left;margin:0;padding:2px 0;}div.bsRlogo a,div.bsRlogoSel a{float:left;}div.bsLogo,div.bsLogoSel{float:left;width:111px;text-align:left;height:auto;padding:2px 4px;margin:2px 0;white-space:nowrap;overflow:hidden;}div.bsLogoSel,div.bsRlogoSel{border:1px solid #ddd;background:#f1f1f1;}div.bsLogo,div.bsRlogo{border:1px solid #fff;background:#fff;}div.bsLogo a,div.bsLogoSel a{display:block;height:16px;line-height:16px;padding:0 0 0 24px;text-decoration:none;float:left;overflow:hidden;}div.bsLogoSel a,div.bsRlogoSel a{color:#000;border:none;}div.bsLogo a,div.bsRlogo a{color:#666;border:none;}div.bsLogoLink{width:121px;overflow:hidden;background:#FFF;float:left;margin:3px 0;}#bsPanel{position:absolute;z-index:100000000;font-size:12px;width:258px;background:url("9155e44e-f873-4c3c-9963-77d48297c895_files/background-opaque-darkCA53L7XZ.png");padding:6px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}div.bsClear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden;}div.bsPopupAwd{background: url("9155e44e-f873-4c3c-9963-77d48297c895_files/bshare_box_sprite2CA9ZG66J.gif") no-repeat top left;background-position:0 -624px;width:18px;padding-left:3px;text-align:center;float:left;margin-left:2px;height:15px;font-size:12px;color:#fff;overflow:hidden;}div.bsRlogo .bsPopupAwd,div.bsRlogoSel .bsPopupAwd{float:left;margin:5px 0 0 -14px;}a.bsSiteLink{text-decoration:none;color:#666;}a.bsSiteLink:hover{text-decoration:underline;}a.bshareDiv{overflow:hidden;height:16px;line-height:18px;font-size:14px;color:#333;padding-left:0;}a.bshareDiv:hover{text-decoration:none;}div.bsTitle{padding:0 8px;border-bottom:1px solid #e8e8e8;color:#666;background:#f2f2f2;text-align:left;}div.buzzButton{cursor:pointer;}div.bsRlogo,div.bsRlogoSel{width:68px;float:left;margin:0;padding:2px 0;}div.bsRlogo a,div.bsRlogoSel a{float:left;}div.bsLogo,div.bsLogoSel{float:left;width:111px;text-align:left;height:auto;padding:2px 4px;margin:2px 0;white-space:nowrap;overflow:hidden;}div.bsLogoSel,div.bsRlogoSel{border:1px solid #ddd;background:#f1f1f1;}div.bsLogo,div.bsRlogo{border:1px solid #fff;background:#fff;}div.bsLogo a,div.bsLogoSel a{display:block;height:16px;line-height:16px;padding:0 0 0 24px;text-decoration:none;float:left;overflow:hidden;}div.bsLogoSel a,div.bsRlogoSel a{color:#000;border:none;}div.bsLogo a,div.bsRlogo a{color:#666;border:none;}div.bsLogoLink{width:121px;overflow:hidden;background:#FFF;float:left;margin:3px 0;}#bsPanel{position:absolute;z-index:100000000;font-size:12px;width:258px;background:url("9155e44e-f873-4c3c-9963-77d48297c895_files/background-opaque-darkCA53L7XZ.png");padding:6px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}div.bsClear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden;}div.bsPopupAwd{background: url("9155e44e-f873-4c3c-9963-77d48297c895_files/bshare_box_sprite2CA9ZG66J.gif") no-repeat top left;background-position:0 -624px;width:18px;padding-left:3px;text-align:center;float:left;margin-left:2px;height:15px;font-size:12px;color:#fff;overflow:hidden;}div.bsRlogo .bsPopupAwd,div.bsRlogoSel .bsPopupAwd{float:left;margin:5px 0 0 -14px;}
嵌入式 探讨父子线程、进程终止顺序不同产生的结果
Linux下编程,线程、进程退出顺序问题纷纷扰扰,如果父进程/线程先于子进程/线程终止,系统会做什么处理呢?反之,如果子进程/线程先于父进程/线
程终止,系统又会做什么处理呢?下面是我个人平时在笔记上做的一些象征性的总结,如果有疑问之处,大可提出,我一直认为怀疑是人类进步的根本所在。
一、线程
Linux线程创建函数为pthread_create(),默认规则是谁创建子线程,谁就要负责子线程的资源回收,当父线程退出后,子线程也随着退出。所以,一般情况下,父线程退出时都要确保子线程已经退出,所以会使用pthread_join()函数阻塞等待子线程的退出信号/标识。
pthread_detach(threadid)函数的功能是使线程ID为threadid的线程处于分离状态(可以为非父子关系),一旦线程处于分离
状态,该线程终止时底层资源立即被回收;否则终止子线程的状态会一直保存占用系统的资源直到主线程调用
pthread_join(threadid,NULL)获取线程的退出状态。被创建的子线程也可以自己分离自己,子线程调用
pthread_detach(pthread_self())就是分离自己,因为pthread_self()这个函数返回的就是自己本身的线程ID。
1)父线程先于子线程终止
父线程先于子线程,则子线程为异常退出
,那肯定没有使用阻塞非分离函数pthread_join,分2种情况:
a)子线程已与父线程分离,如调用线程分离函数pthread_detach,则资源被自动回收释放。
b)子线程未与父线程分离,则资源无法释放,造成了资源浪费和系统臃肿(这种情况,我看有些资料上说系统也能自动释放子线程的资源,如关闭描述符,释放内
存空间等等,但个人做过一些测试,比如在子线程中分配很多空间等,进程退出后,top查看内存状态时还存在)。
2)子线程先于父线程终止
也分2种情况:
a)正常情况:子线程调用了线程分离函数ptread_detach(),或父线程调用了等待线程结束函数pthread_join()。
b)异常情况:如果上面二者都为调用,则为子线程分配的资源无法得到释放。
二、进程
一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child
process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
1)父进程先于子进程终止
当父进程先退出时,系统会让init进程接管子进程,该子线程成为了孤儿进程。
2)子进程先于父进程终止
分为2种情况:
a)正常情况:父进程调用了wait函数 (非父子进程则用waitpid函数),此时父进程会等待子进程结束。
b)父进程又没有调用wait函数
(非父子进程则未调用waitpid函数),此种情况子进程进入僵死状态即僵尸进程,并且会一直保持下去直到系统重启。子进程处于僵死状态时,内核只保存进程的一些必要信息以备父进程所需。此时子进程始终占有着资源,同时也减少了系统可以创建的最大进程数。
僵死状态:一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占有的资源)的进程被称为僵死进程(zombie)。ps命令将僵死进程的状态打印为Z
。