Chinaunix

标题: 向perl脚本发送HUP信号 只有第一次成功 [打印本页]

作者: 风吹不倒    时间: 2011-05-26 20:58
标题: 向perl脚本发送HUP信号 只有第一次成功
本帖最后由 风吹不倒 于 2011-05-26 21:01 编辑

大家好:
          最近参照仙子的作品写了个脚本 让自身进入后台;能接受HUP信号重启脚本,但目前发现,当我第一次kill -1 pid时是成功的,但第二次再发送信号却没了反应,象是没有接收信号一样,代码如下,大家帮我看看
  1. use strict;
  2. use IO::File;
  3. use POSIX;

  4. my $pid_file='/home/perl.pid';
  5. my $quit=0;

  6. $SIG{TERM} = $SIG{INT} =\&do_term;
  7. $SIG{HUP}  = \&DoHup;

  8. if (-e $pid_file) {
  9.     open PIDFILE,"<$pid_file" or die "$!\n";
  10.     my $pid=<PIDFILE>;
  11.         close PIDFILE;
  12.     die "Server already running with pid $pid" if kill 0 => $pid;
  13.     warn "Removing old PID file for $0";
  14.     die "Can't unlink PID file $pid_file"  unless (-w $pid_file && unlink $pid_file);
  15. }

  16. open NEWPID,">$pid_file" or die "Can't create pid file:$!";
  17. my $pid= daemon();
  18. print NEWPID "$pid\n";
  19. close NEWPID;

  20. open LOGA," >>/home/test.log ";
  21. syswrite LOGA,"$quit\n";
  22. my $count;
  23. while (!$quit) {
  24.         $count++;
  25.         syswrite LOGA,"hello a $count\n";
  26.         sleep 1;
  27. }

  28. sub daemon{
  29.         die "can't fork!" unless defined (my $child = fork);
  30.         exit 0 if $child;
  31.         setsid();
  32.         print "Server start with pid $\n";
  33.         open(STDIN,"</dev/null");
  34.         open(STDOUT,">/dev/null");
  35.         open(STDERR,">&STDOUT");
  36.         chdir '/';
  37.         umask(0);
  38.         $ENV{PATH} = '/bin:/sbin/:/usr/bin:/usr/sbin';
  39.         return $;
  40. }

  41. sub do_term{
  42.         unlink $pid_file;
  43.         $quit++;
  44. }
  45. sub DoHup{
  46.         warn "received SIGHUP,prepare to reload...\n";
  47.         unlink $pid_file;
  48.         exec '/usr/bin/perl','/home/daemon.pl';
  49. }
复制代码

作者: yybmsrs    时间: 2011-05-26 20:58
Signals are tricky beasts. When you exec to restart your program, the reborn version inherits a set of blocked signals from its parent. Inside a signal handler, that signal is blocked. So if your signal handler simply called exec right away, the new process would have SIGHUP blocked. You could only restart your program once!


书上的
作者: 风吹不倒    时间: 2011-05-26 22:11
回复 2# yybmsrs

谢谢!!!有方向了 我再去找找解决方法
作者: 风吹不倒    时间: 2011-05-26 23:15
暂时先这样解决了
  1. my $signals = POSIX::SigSet->new(SIGHUP,SIGTERM,SIGINT);
  2. sigprocmask(SIG_UNBLOCK,$signals);
复制代码

作者: yybmsrs    时间: 2011-05-27 08:53
不错。书上的例子:
  1. use POSIX qw(:signal_h sigprocmask);

  2. my $SELF = "/path/to/my/program";
  3. my @ARGS = @ARGV;   # save for later

  4. $SIG{HUP} = \&phoenix;

  5. # your program

  6. sub phoenix {
  7.   # make signals harmless
  8.   for my $nal (qw[ALRM CHLD HUP INT PIPE TERM]) {
  9.     $SIG{$nal} = sub {  };
  10.   }

  11.   # reenable them
  12.   my $s = POSIX::SigSet->new;
  13.   my $t = POSIX::SigSet->new;
  14.   sigprocmask(SIG_BLOCK, $s, $t);

  15.   # and restart
  16.   print "Restarting\n";
  17.   exec $SELF => @ARGS;
  18.   die "Couldn't exec $SELF => @ARGS\n";
  19. }
复制代码

作者: 兰花仙子    时间: 2011-05-27 09:49
要设置SIGBLOCK和SIGUNBLOCK。我的daemon都可以自由kill -HUP N次。
作者: 风吹不倒    时间: 2011-05-27 14:33
回复 5# yybmsrs


    不是太懂,屏蔽信号后执行再exec,不是又阻塞了吗?
作者: 风吹不倒    时间: 2011-05-27 14:36
回复 6# 兰花仙子


    当时只想要让进程进入后台,就忽视了信号屏蔽这一块,谢谢你的pdf~




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2