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

[经验分享] Perl语言的多线程(二)

[复制链接]

尚未签到

发表于 2015-12-26 01:08:03 | 显示全部楼层 |阅读模式
  很多时候使用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。


  


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

运维网声明 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-156344-1-1.html 上篇帖子: perl debug 下篇帖子: Perl 与Form
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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