注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

云之南

风声,雨声,读书声,声声入耳;家事,国事,天下事,事事关心

 
 
 

日志

 
 
关于我

专业背景:计算机科学 研究方向与兴趣: JavaEE-Web软件开发, 生物信息学, 数据挖掘与机器学习, 智能信息系统 目前工作: 基因组, 转录组, NGS高通量数据分析, 生物数据挖掘, 植物系统发育和比较进化基因组学

网易考拉推荐

【转】Perl语言的多线程(二)  

2012-05-17 10:52:09|  分类: perl&bioperl |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

    http://www.cnblogs.com/joechen/archive/2009/04/27/1444602.html

很多时候使用perl多线程可以达到很不错的效果,可以节约很多时间完成很复杂的工 作。但通过perl threads模块的描述文件可以看到,它也有很多缺点。比如说在使用perl多线程的时候,必须的保证所有引用的模块都是支持thread。而在实际应 用中,我们很难做到这样。比如我们要多线程,但同时要应用OLE模块去操作activex。 此用例应该是一种很常见的用例。那是不是意味着此时我们不得不放弃使用多线程呢。 非也, 本文介绍一种可以使用多线程和ole的例子。

 在http://www.cpan.org/官方网站上对这种情况给出的方案是:

If the module will only be used inside a thread, you can try loading the module from inside the thread entry point function using require (and import if needed):

     sub thr_func { require Unsafe::Module # Unsafe::Module->import(...); .... }

      If the module is needed inside the main thread, try modifying your application so that the module is loaded (again using require and ->import()) after any threads are started, and in such a way that no other threads are started afterwards。

再次,主要讨论一下第二种情况,既主要是该非thread模块放到方法中引用。下面是一个demo。

 

【转】Perl语言的多线程(二) - 云之南 - 云之南
use threads;
use threads::shared;
use Thread::Queue;
no warnings 
'threads';

# Time 
out const
my $TIMEOUT : shared;
$TIMEOUT 
= 1;
# the sig 
for end thread 
my $TERM : shared;
$TERM 
= 0;
#my $excel;

$SIG{
'INT'= $SIG{'TERM'= sub{ print("\n>>> Terminating <<<\n"); $TERM=1;};
$SIG{
'KILL'= sub{ printf("%3d <- Killed\n", threads->tid()); 
                    threads
->detach() if !threads->is_detached();
                    threads
->exit(); };

sub ThreadWatcher
{
    my $queue 
= shift;
    my 
%timers;
    
    
while(!$TERM)
    {
        #print 
"ThreadWatcher -- TERM : $TERM\n";
        
while(my $tid = $queue->dequeue_nb())
        {
            
if (! defined($timers{$tid}{'timeout'= $queue->dequeue()) ||
                
! defined($timers{$tid}{'thread'}  = threads->object($tid)))
            {
                # No timeout 
- unregister thread
                delete($timers{$tid});
            }
        }
               
        
        
foreach my $tid (keys(%timers))
        {
            #print 
"$timers{$tid}{'thread'} \n";
            
if(--$timers{$tid}{'timeout'< 0)
            {
                print 
"thread $timers{$tid}{'thread'} will be killed.\n";
                $timers{$tid}{
'thread'}->kill('KILL');
                delete($timers{$tid});
            }
        }
        
        # tick tock
        sleep(
1);
    }
}

sub Worker
{
    #eval {use Win32::OLE::Variant;};
    
    my ($queue, $dataqueue) 
= @_;
    # 
get the thread id and register with watch
    my $tid 
= threads->tid();
    printf(
"Working -> %3d\n", $tid);
    $queue
->enqueue($tid, $TIMEOUT);
    print 
"Worker -- TERM : $TERM\n";
    
while(!$TERM)
    {
        
        #my $App 
= $dataqueue->dequeue();
        my $data 
= $dataqueue->dequeue();
        #deal with the data
        #print 
"Worker -- DATA : $App\n";
        print 
"Worker -- DATA : $data\n";
        
        #my $var 
= Win32::OLE::Variant->new(VT_BSTR, $data);
        #print 
"Worker VAR: $var\n";
    }
    
    # Remove signal handler
    $SIG{
'KILL'= sub {};

    # Unregister with timer thread
    $queue
->enqueue($tid, undef);

    # Tell user we
're done
    printf("%3d <- Finished\n", $tid);
   
    threads
->detach() if ! threads->is_detached();
    threads
->exit();
}

# create time thread

my $watchQueue 
= Thread::Queue->new();
threads
->create('ThreadWatcher', $watchQueue)->detach();

# create work thread
my $dataQueue 
= Thread::Queue->new();
threads
->create('Worker', $watchQueue, $dataQueue);

NoneSafeModelScript(
'C:\Joe_Chen\Perl_Projects\Threads\update.xlsx');

WairLongTime(
10);


sub WairLongTime
{
    my $temp 
= $_[0];
    $temp 
= $temp * 10000000;
    
for(my $index = 0; $index < $temp; $index++)
    {
        $index 
* $index;
    }
    
return $index;
}

sub NoneSafeModelScript
{
    eval 
'use Win32::OLE';  
    eval 
'use Win32::OLE::Variant';
    
    my $excel;
    
for(my $index = 0; $index < 600; $index++)
    {
        print 
"Getting the Excel ActiveObject. Try # $index \n";
        WairLongTime(
1);
        eval
        {
            $excel 
= Win32::OLE->GetActiveObject('Excel.Application'|| Win32::OLE->new('Excel.Application''Quit');
        };
        
if($@ or $excel == undef)
        {
            print 
"Unsuccessful: $@ \n";
            
if($index == 599)
            {
                print 
"ERROR:Don\'t got the Excel Application";
            }
        }
        
else
        {
            last;
        }
    }
    
    my $path 
= $_[0];
    
    my $book 
= $excel->workbooks->open($path);
    my $sheet 
= $book->worksheets(1);
    
    my $values 
= $sheet->Range("A1:D5")->{Value};
    my $row_counts 
= $sheet->Range("A1:C3")->{Rows}->{Count};
    my $column_counts 
= $sheet->Range("A1:C3")->{Columns}->{Count};
        
    print 
"NoneSafeModelScript : $row_counts \n";
    print 
"NoneSafeModelScript : $column_counts \n";
    
    
for(my $row=1; $row<$row_counts + 1; $row++)
    {
        my $array_ref 
= $sheet->Cells($row,1)->{Value};
        print 
"NoneSafeModelScript : $array_ref \n";
        
        my $var 
= Variant(Win32::OLE::Variant->VT_BSTR, $array_ref);
        my $v 
= ref($var);
        #my $v 
= $var->Type();
        print 
"NoneSafeModelScript VAR: $var\n";
        print 
"NoneSafeModelScript VAR: $v\n";
        #$dataQueue
->enqueue($var);
        $dataQueue
->enqueue($array_ref);
        WairLongTime(
2);
    }
    
    my $v 
= Variant(VT_DATE, "April 1 99");
    print $v
->Type, "\n";
    print $v
->Date(DATE_LONGDATE), "\n";
    print $v
->Date("ddd',' MMM dd yy"), "\n";
    
    print Win32::OLE::Variant
->VT_BSTR , "\n";
    
    $book
->Close;
    $excel
->Quit;
}

sub Wrap
{
    my $value 
= $_[0];
    my $var 
= Variant(VT_DATE, 'Jan 1,1970');
    print 
"Wrap : $var \n"
    
return $var;
}

 

在此例子中,用到了queue,它的作用是将非thread 安全的数据通过管道传输,这样能避免他们互相调用。

  评论这张
 
阅读(864)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016