zoukankan      html  css  js  c++  java
  • perl DBI超时控制

    名字:
    
    Sys::SigAction  Perl 拓展用于一致的信号处理
    
     #do something non-interrupt able
           use Sys::SigAction qw( set_sig_handler );
           {
              my $h = set_sig_handler( 'INT' ,'mysubname' ,{ flags => SA_RESTART } );
              ... do stuff non-interrupt able
           } #signal handler is reset when $h goes out of scope
    
    摘要:
    
    这个模块实现了"set_sig_handler()", 它设置了一个信号处理器 返回一个导致信号处理器
    
    被重置先先前值的对象
    
    "timeout_call() 是实现通过一个超时参数,一个code引用和可选的参数,
    
    执行代码引用封装使用一个alarm 超时  
    
    描述:
    
    在5.8版本之前, perl实现了不安全的信号处理。
    
    这哥之所以认为不安全,是因为有一个风险 一个信号会到达和辈出当perl时改变内部数据结构。
    
    Perl 5.8.0 和后面的版本实现了安全的信号处理在支持POSIX sigaction() function.
    
    来自PERL 5.8.2 手册页:
    
    
    因此  'deferred signal'  方法导致一些系统调用被重试在信号之前被调用
    
    这个打破了 DBD-ORACLE的超时逻辑 
    
    对于早期的PERL版本,这个可以是特别恼火的,
    
    对于实例,当主机是不可达的:
    
     "DBI->connect()" hangs 几分钟在返回错误前
     
     (甚至不能用control-C中断)
     
    这是因为信号出现被延迟 结果是不能实现超时 
    
    [oracle@yyjk sbin]$ cat testdbi2.pl 
    use DBI;
    no warnings;
    
    use DBI;
    use HTTP::Date qw(time2iso str2time time2iso time2isoz);
    use Net::SMTP;
    use Encode;
    use JSON;
    my $dbip='10.2.120.192';
    my $dbname='uacdb';
    my $dbuser='uac';
    my $dbpass='uac_123';
    $dbh1 = DBI->connect( "dbi:Oracle://$dbip:1521/$dbname", $dbuser, $dbpass );
    [oracle@yyjk sbin]$ time perl testdbi2.pl 
    DBI connect('//10.2.120.192:1521/uacdb','uac',...) failed: ORA-12170: TNS: 连接超时 (DBD ERROR: OCIServerAttach) at testdbi2.pl line 13.
    
    real    1m0.186s
    user    0m0.101s
    sys    0m0.015s
    
      Or as the author of bug #50628 pointed out, might probably better be
        written as:
    
           eval {
              local $SIG{ALRM} = sub { die "timeout" };
              eval {
                 alarm 2;
                 $sth = DBI->connect(...);
                 alarm 0;
              };
              alarm 0;
              die if $@;
           };
    
    
    [oracle@yyjk sbin]$ cat testdbi1.pl 
    use DBI;
    no warnings;
    
    use DBI;
    use HTTP::Date qw(time2iso str2time time2iso time2isoz);
    use Net::SMTP;
    use Encode;
    use JSON;
    use Sys::SigAction qw( set_sig_handler );
    my $dbip='10.2.120.192';
    my $dbname='uacdb';
    my $dbuser='uac';
    my $dbpass='uac';
    eval {
         my $h = set_sig_handler( 'ALRM' ,sub { die; } ); #数据库连接超时后的返回结果
           alarm(5); #设置为5秒超时
          $dbh1 = DBI->connect( "dbi:Oracle://$dbip:1521/$dbname", $dbuser, $dbpass );
          alarm(0);
         };a
    if ($@){
       print '11111111111111'."
    ";
    }
    else{
      print '222222222222222'."
    ";
    };
    You have mail in /var/spool/mail/oracle
    [oracle@yyjk sbin]$ 
    [oracle@yyjk sbin]$ time perl testdbi1.pl 
    11111111111111
    
    real    0m5.104s
    user    0m0.100s
    sys    0m0.019s
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    FreeRTOS学习目录
    ESP32随笔汇总
    FPGA开发随笔汇总
    manim在windows系统下安装
    16、频率域滤波
    15、频率域滤波基础——傅里叶变换计算及应用基础
    14、OpenCV实现图像的空间滤波——图像锐化及边缘检测
    13、OpenCV实现图像的空间滤波——图像平滑
    12、OpenCV实现图像的直方图处理
    生成预加载镜像以及设备树
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13348925.html
Copyright © 2011-2022 走看看