固定时间多线程清理进程

#!/usr/bin/env perl
use File::Basename;
our $PATH;
BEGIN {
    use Cwd 'abs_path';
    $PATH = abs_path($0);
    $PATH =~ s/\\/\//g;
    chdir($PATH);
    $PATH =~ s/\/[^\/]+$//o;
    unshift(@INC,$PATH.'/lib');
}

use strict;
use warnings;
$| = 1;

my $VERSION = "0.0.1";
my $NAME    = basename($0,('.exe','.pl'));
use Data::Dumper;

# global configuration file
use Config::Simple;
my $conf = Config::Simple->new("watchdog.conf");
# 格式
# httpd=httpd/01:01:01
# smbd=smbd/01:01:01
my %config = $conf->vars();

# run the app in daemon mode
use App::Daemon qw( daemonize );
$App::Daemon::logfile    = "kill.log";
$App::Daemon::pidfile    = "kill.pid";
#$App::Daemon::l4p_conf   = "myconf.l4p";
$App::Daemon::background = 1;
$App::Daemon::as_user    = "root";
$App::Daemon::as_group   = "root";

$App::Daemon::kill_retries = 60 * 30;
use Log::Log4perl qw(:levels);
$App::Daemon::loglevel   = $DEBUG;
daemonize();

my $logger = Log::Log4perl->get_logger('Transfer');
# we use the strftime function to print the time string
use POSIX qw(strftime);
use Time::Local;

# use the multithreading to deal the messages
use threads (    'yield',
                 'stack_size' => 64*4096,
                 'exit' => 'threads_only', 'stringify' 
			);

use threads::shared;
our $continue :shared = 1;
while($continue){
	foreach my $line (keys(%config)) {
		my ($process, $time) = split('\/', $config{$line});
		my $c = threads->create(\&kill_process, $process, $time);
		$c->detach();
	}
	sleep(5000);
}

# start one thread to kill....
sub kill_process {
    my ($process_name, $time) = @_;
	if(gettime()>=str2time($time)){
		pkill($process_name);
		$logger->info("Kill the process ".$process_name." at ".$time);
	}
}

# 检测进程状态,返回PID
# 如果同进程不在运行,则返回空
sub pcheck
{
    # grep 排除perl本身的进程
    my $cmd = "ps -ef | grep " . shift . " | grep -v grep | grep -v perl | awk '{print \$2}'";
    my $ret = `$cmd` ;
    chomp $ret;
    #如果有多个进程PID,则返回第一个pid
    if( $ret =~ /\n/ ){
        $ret = ( split /\n/, $ret )[0] ; 
    }
	return $ret;
}

# 结束进程,返回成功与否
# 0 表示成功
sub pkill{
    my $cmd = "killall ".shift;
    my $ret = `$cmd`;
    print $? ; 
}

############
## 获取时间s
############
sub gettime{
   my ($sec,$min,$hour,$day,$mon,$year) = (localtime(time));
   return ($hour*60+$min)*60+$sec; 
}

sub str2time{
   my $time = shift;
   my ($hour, $min, $sec) = split(':', $time);
   $hour =~ s/^[0]*(.*)/$1/ig;
   $min =~ s/^[0]*(.*)/$1/ig;
   $sec =~ s/^[0]*(.*)/$1/ig;
   return ($hour*60+$min)*60+$sec; 
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#   重新定义信号量,转发中断等处理信号,防止数据丢失
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$SIG{KILL} = $SIG{INT} = $SIG{TERM} = sub {
	halt();
};

$SIG{__DIE__} = sub {
	$logger->error("catched a die signal.".$!);
	# Check save thread's state
	$continue = 0;
};

sub halt{
	$logger->debug("received a STOP SIG");
	# begin stopping the server
	$continue = 0;
	$logger->info("server stopping.");
}
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#   重新定义信号量结束
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Perl分类目录。将固定链接加入收藏夹。

发表回复