Perl线程机制学习

说来惭愧,用了好多年perl,都没有写过多线程的应用,甚至一度以为perl是不支持线程的,想要并发就只能用POE搞搞调度。直到今天看了这篇文章才知道,原来perl不但有线程模型,甚至都已经deprecate过一个早期的线程模型了,于是就好好学习了一下目前正在被推荐的ithreads模型,并查看了一下相应的cpan关于threadsthreads::shared的文档。

这才发现,perl不但支持线程,而且还比较易学易用。总体来说,有如下贴心属性:

  1. 线程创建方便:
    一个perl线程的创建只需要use threads并调用threads->create(),传入相应的代码块或函数引用就行。子线程被创建之后自动开始运行,非常省力。
    use threads;
    $t = threads->create(sub { print("I am a thread\n"); });
     
  2. 线程管理方便:
    对于线程的执行控制,有两种方式,一种是join(),一种是detach()。所谓join()就是在主线程中等待子线程的执行返回值,然后再继续执行后续代码,而在调用线程的join()方法之前,子线程与主线程的执行是分开的。而detach()则是告诉perl解释器主线程不关心子线程的执行结果,所以该子线程在完成任务之后就是自动退出,同时释放自己所占有的资源,而不用主线程再操心。
    $t->join() #wait for $t to finish and then go on
    
    ...
    
    $t->detach() #$t will finish its job then release all the resources
     
  3. 数据共享安全,互斥方便:
    所谓的共享安全实际上就是不共享,使用threads模块创建的线程,里面的变量全都是由线程私有的,因此如果需要共享数据,则需要显示地use threads::shared;并使用shared后缀或shared()方法来生命变量。这样,实际上是靠增加代码的透明度来减少粗心出错的可能性。
    而变量的互斥也非常简单,可以直接使用lock()函数来锁住变量,从而达到互斥的效果。锁的生命周期控制也很简单,就是以代码块的结束为界,代码快结束,锁自动释放,省去了繁琐易遗漏易出错的释放锁函数的调用,有点像ACE里面的guard。 
    { 
        lock( $share );
        $share++
     } #lock released here
     
  4. 对典型应用有成型支持。
     多线程模式下,最典型的应用莫过于生产者-消费者模型,因此,CPAN上提供了Thread::Queue模块来执行多个线程对于单个队列的访问同步和互斥控制。
    另外,对于线程池,CPAN
    上也提供了现成的Thread::Pool模块可用,可以说,善用CPAN的话, perl程序员真的会很舒服。

至于该线程模型的性能倒是没有时间细测,总之先学会用再说。一个多线程并发模型只需要15分钟学会并能够开始写东西,足以说明它还是挺顺应直觉的。

本文网址:http://blog.perlfect.me/2010/07/13/learning-perl-ithread-model.html

More Reading
Older// 世界杯杂感
comments powered by Disqus