设为首页 收藏本站
查看: 845|回复: 0

[经验分享] Perl线程的生命周期

[复制链接]

尚未签到

发表于 2017-5-17 08:03:20 | 显示全部楼层 |阅读模式
本文和大家重点讨论一下Perl线程的生命周期,主要包括创建Perl线程,join方法和detach方法两大部分内容,希望通过本文的介绍你对Perl线程的生命周期有一定的认识。

Perl线程的生命周期

创建Perl线程

Perl线程作为Perl中的一种实体,其一生可以粗略的分为创建,运行与退出这三个阶段。创建使得Perl线程从无到有,运行则是Perl线程完成其主要工作的阶段,退出自然就是指Perl线程的消亡。Perl线程的运行和普通函数的执行非常类似,有其入口参数,一段特定的代码流程以及执行完毕后返回的一个或一组结果,唯一与普通函数调用的不同之处就在于新建Perl线程的执行与当前Perl线程的执行是并行的。

Perl里创建一个新的Perl线程非常简单,主要有两种方法,他们分别是:

使用threads包的create()方法,例如

清单3.通过create()方法创建Perl线程   


use threads;
   sub say_hello  {
  printf("Hellothread!@_.\n");
  return(rand(10));  
}   
my$t1=threads->create(\&say_hello,"param1","param2");  
my$t2=threads->create("say_hello","param3","param4");  
my$t3=threads->create(  
sub{
  printf("Hellothread!@_\n");  
  return(rand(10));  
},  "param5",  "param6");   
使用async{}块创建Perl线程,例如

清单4.通过async{}块创建Perl线程   


#!/usr/bin/perl  #  
use threads;   
my $t4=async{
  printf("Hellothread!\n");
};   

join方法和detach方法

Perl线程一旦被成功创建,它就立刻开始运行了,这个时候你面临两种选择,分别是join或者detach这个新建Perl线程。当然你也可以什么都不做,不过这可不是一个好习惯,后面我们会解释这是为什么。

我们先来看看join方法,这也许是大多数情况下你想要的。从字面上来理解,join就是把新创建的Perl线程结合到当前的主Perl线程中来,把它当成是主Perl线程的一部分,使他们合二为一。join会触发两个动作,首先,主Perl线程会索取新建Perl线程执行结束以后的返回值;其次,新建Perl线程在执行完毕并返回结果以后会自动释放它自己所占用的系统资源。例如

清单5.使用join()方法收割新建Perl线程   


#!/usr/bin/perl  #  
use threads;   
sub func{  
  sleep(1);  
  return(rand(10)); #return (int(rand(10)));
}  
my$t1=threads->create(\&func);  
my$t2=threads->create(\&func);   
printf("dosomethinginthemainthread\n");   
my$t1_res=$t1->join();  
my$t2_res=$t2->join();   
printf("t1_res=$t1_res\nt2_res=$t2_res\n");   
由此我们不难发现,调用join的时机是一个十分有趣的问题。如果调用join方法太早,新建Perl线程尚未执行完毕,自然就无法返回任何结果,那么这个时候,主Perl线程就不得不被阻塞,直到新建Perl线程执行完毕之后,才能获得返回值,然后资源会被释放,join才能结束,这在很大程度上破话了Perl线程之间的并行性。相反,如果调用join方法太晚,新建Perl线程早已执行完毕,由于一直没有机会返回结果,它所占用的资源就一直无法得到释放,直到被join为止,这在很大程度上浪费了宝贵的系统资源。因此,join新建Perl线程的最好时机应该是在它刚刚执行完毕的时候,这样既不会阻塞当前Perl线程的执行,又可以及时释放新建Perl线程所占用的系统资源。

我们再来看看detach方法,这也许是最省心省力的处理方法了。从字面上来理解,detach就是把新创建的Perl线程与当前的主Perl线程剥离开来,让它从此和主Perl线程无关。当你使用detach方法的时候,表明主Perl线程并不关心新建Perl线程执行以后返回的结果,新建Perl线程执行完毕后Perl会自动释放它所占用的资源。

一个新建Perl线程一旦被detach以后,就无法再join了。当你使用detach方法剥离Perl线程的时候,有一点需要特别注意,那就是你需要保证被创建的Perl线程先于主Perl线程结束,否则你创建的Perl线程会被迫结束,除非这种结果正是你想要的,否则这也许会造成异常情况的出现,并增加程序调试的难度。

本节的开始我们提到,新Perl线程被创建以后,如果既不join,也不detach不是一个好习惯,这是因为除非明确地调用detach方法剥离Perl线程,Perl会认为你也许要在将来的某一个时间点调用join,所以新建Perl线程的返回值会一直被保存在内存中以备不时之需,它所占用的系统资源也一直不会得到释放。然而实际上,你打算什么也不做,因此宝贵的系统资源直到整个Perl应用结束时才被释放。同时,由于你即没有调用join有没有调用detach,应用结束时Perl还会返回给你一个Perl线程非正常结束的警告。

Perl线程的消亡

大多数情况下,你希望你创建的Perl线程正常退出,这就意味着Perl线程所对应的函数体在执行完毕后返回并释放资源。例如在清单5的示例中,新建Perl线程被join以后的退出过程。可是,如果由于detach不当或者由于主线因某些意外的异常提前结束了,尽管它所创建的Perl线程可能尚未执行完毕,但是他们还是会被强制中止,正所谓皮之不存,毛将焉附。这时你也许会得到一个类似于“Perlexitedwithactivethreads”的警告。

当然,你也可以显示地调用exit()方法来结束一个Perl线程,不过值得注意的是,默认情况下,如果你在一个Perl线程中调用了exit()方法,其他Perl线程都会随之一起结束,在很多情况下,这也许不是你想要的,如果你希望exit()方法只在调用它的Perl线程内生效,那么你在创建该Perl线程的时候就需要设置’exit’=>’thread_only’。例如


清单7.为某个Perl线程设置’exit’=>’thread_only’属性   


#!/usr/bin/perl  #
  use threads;   
su bsay_hello{  
  printf("Hellothread!@_.\n");  
  sleep(10);  
  printf("Bye\n");  
}
sub quick_exit{  
  printf("Iwillbeexitinnotime\n");  
  exit(1);  
}   
my $t1=threads->create(\&say_hello,"param1","param2");  
my $t2=threads->create({'exit'=>'thread_only'},\&quick_exit);   
$t1->join();  
$t2->join();   
如果你希望每个Perl线程的exit方法都只对自己有效,那么在每次创建一个新Perl线程的时候都去要显式设置’exit’=>’thread_only’属性显然有些麻烦,你也可以在引入threads包的时候设置这个属性在全局范围内有效。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-378292-1-1.html 上篇帖子: perl-文件读写 下篇帖子: Perl Notes(I)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表