博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Perl语言的多线程(二)
阅读量:5892 次
发布时间:2019-06-19

本文共 4658 字,大约阅读时间需要 15 分钟。

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

 在官方网站上对这种情况给出的方案是:

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。

 

ContractedBlock.gif
ExpandedBlockStart.gif
Code
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 安全的数据通过管道传输,这样能避免他们互相调用。

转载于:https://www.cnblogs.com/licheng/archive/2009/11/27/1612325.html

你可能感兴趣的文章
linux下单节点oracle数据库间ogg搭建
查看>>
swift三方库
查看>>
POJ NOI0105-42 画矩形
查看>>
Java 数组在内存中的结构
查看>>
《关爱码农成长计划》第一期报告
查看>>
学习进度表 04
查看>>
谈谈javascript中的prototype与继承
查看>>
时序约束优先级_Vivado工程经验与各种时序约束技巧分享
查看>>
minio 并发数_MinIO 参数解析与限制
查看>>
mysql 应用程序是哪个文件夹_Mysql 数据库文件存储在哪个目录?
查看>>
mysql半同步和无损复制_MySQL半同步复制你可能没有注意的点
查看>>
python编译exe用于别的电脑上_Python安装教程(推荐一款不错的Python编辑器)
查看>>
flash back mysql_mysqlbinlog flashback 使用最佳实践
查看>>
hive中如何把13位转化为时间_sqoop1 导入 hive parquet 表中 时间戳调整为日期
查看>>
mysql书外键_[转] mysql 外键(Foreign Key)的详解和实例
查看>>
mysql存储引擎模式_MySQL存储引擎
查看>>
mysql5002_mysql新手进阶02
查看>>
python类 del_全面了解Python类的内置方法
查看>>
前后端传图片用base64好吗_前后端分离 前台传base64的图片 tp5.1.1进行处理
查看>>
java对象的排序_Java对象排序两种方法
查看>>