Perl进程间通讯研究


Perl进程间通讯前几天做了一个比较简单的东西,但感觉比较意思就在这里记下来。大概的需求是这样的:有一个程序在会产生一些警告信息并保存在/var/log/alert中的。如果有新的警告信息时就要在服务器上发出警告的声音,但启动是通过web界面的而不是在命令行。

  刚开始想到步骤是这样的:

  1、 因为是要在后台运行,肯定是fork一个子进程,父进程退出而不会使web程序阻塞在此,

  2、 然后再fork一个子进程,父进程负责监听日志文件的更新。子进程负责调用声音程序。两者之者用管道通讯。

  3、 要实时监控日志文件的更新,因为不想搞太复杂就用管道的方式:open(LOG,"tail -n 2 -f  /var/log/alert| ") ||die "Unable to open log file $!\n";这样就可以简单的得到文件的实时更新

  4、 要考虑到退出,所以需要一个文件保存进程ID。

  这样实现的代码很简单:

  my $pidfile ="/tmp/alertsounds.pid";

  sub StartAlertSounds{

  my $pid;

  if ($pid = fork()) {

  return;

  } elsif (defined $pid) {

  system("echo pid=$ > $pidfile'");#保存进程ID

  &RunAlertSounds();

  }

  }else {

  die "Can't fork: $!\n";

  }

  }

  sub RunAlertSounds{

  my $pid;

  pipe(README, WRITEME);

  if ($pid = fork()) { #父进程

  close(README);

  open(LOG,"tail -n 2 -f  /var/log/alert| ") ||die "Unable to open log file $!\n";

  while (<LOG>) {

  print WRITEME "Sounds\n";

  }

  close(LOG );

  close(WRITEME);

  }elsif (defined $pid) { #子进程

  close(WRITEME);

  while(<README>){

  system("/usr/bin/sounds/AlertSounds >/dev/null 2>&1");

  }

  close(README);

  }else {

  die "Can't fork: $!\n";

  }

  }

  但测试一下就发现了不少问题:

  1、 退出时open(LOG,"tail -n 2 -f  /var/log/snort/alert| ")所产生的子进程不会一起退出。

  2、 当短时间内(比如1秒)有多条信息过来时,我们希望只产生一条警告声音,但现在会连续响多条。

  3、 有时父进程往管道写数据时子进程不一定能马上收到;

  分析一下就有下面的解决方法:

  1、 使父进程成为进程组的头领进程,然后在父进程退出前给进程组发送退出信号。

  2、 使用锁机制,父进程写数据前锁定。等子进程调用声音程序完成后再解锁。在解锁前如果父进程有监听到新的警告就忽略。简单的一点的锁机制就用一个文件:父进程创建一个空文件表示已经上锁,子进程删除这个文件表示解锁

  3、 这个是因为缓存问题,把管道的缓存设置好就行了。

  修改后的代码如下:

  my $pidfile ="/tmp/alertsounds.pid";

  my $lockfilename="/tmp/sounds.lock";

  sub StartAlertSounds{

  my $pid;

  if ($pid = fork()) {

  return;

  } elsif (defined $pid) {

  setpgrp(0,0);#当前进程成为进程组的头领

  $SIG{INT} = \&catch_zap;   # INT信号处理

  $SIG{QUIT} = \&catch_zap;     # QUIT信号处理

  system("echo $ > $pidfile'");#保存进程ID

  &RunAlertSounds();

  }

  }else {

  die "Can't fork: $!\n";

  }

  }

  sub RunAlertSounds{

  my $pid;

  system("rm -f $lockfilename");

  pipe(README, WRITEME);

  if ($pid = fork()) { #父进程

  close(README);#关闭读端

  select( WRITEME ); #这里一定要选择,不然设置的缓存大小不会对WRITEME有效

  $| = 1;

  open(LOG,"tail -n 2 -f  /var/log/alert| ") ||die "Unable to open log file $!\n";

  while (<LOG>) {

  system(“touch $lockfilename");#加锁

  print WRITEME "Sounds\n";

  }

  close(LOG );

  close(WRITEME);

  waitpid($pid, 0);

  }elsif (defined $pid) { #子进程

  close(WRITEME);#关闭写端

  while(<README>){

  system(“/usr/bin/sounds/AlertSounds >/dev/null 2>&1");

  sleep(1);

  system("rm -f $lockfilename");#解锁

  }

  close(README);

  }else {

  die "Can't fork: $!\n";

  }

  }

  sub catch_zap{

  local $SIG{QUIT} = 'IGNORE';   # 排除自己

  kill(QUIT, -$);         # 通知进程组的所有进程退出

  system("echo > $pidfile");

  exit;

  }

  sub StoptAlertSounds{

  if(-e $pidfile ){

  @pid = `cat $pidfile `;

  kill(QUIT,$pid[0]}) if(defined $pid[0] and $pid[0] ne '');

  }

  }



相关阅读:
php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误
如何正确理解PHP的错误信息
在WIN200和WIN98下Tomcat服务器安装实例
很全的显示阴历(农历)日期的js代码
用php发送带附件的Email
多域控制器环境下Active Directory灾难恢复
关闭系统服务导致Windows XP系统无法识别移动硬盘
在GridView中LinkButton的属性的应用(如何不用选中就删除这一行)
ControlJS优化阿里妈妈广告提高页面脚本的加载速度
菜鸟javascript基础资料整理3 正则
有关FreeBSD的汉化与使用
在XP和Windows Server 2003使用凭据管理中
表单的一些基本用法与技巧
input之怎么清除默认值
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 天使翅膀——类的琴声2(转)作文1900字 无情的人作文150字 浅谈如何进一步做好宣传报道工作 我们就这样归于了平静 职工春节团拜会主持人台词 我发现了蚂蚁的毅力作文 2010南非世界杯经典语录 当哈利波特来到中国以后… 我想对你说作文350字 老师开学自我介绍 走进唐诗作文2000字 XXXX年教师述职报告范文 亲爱的,没有了如果……我就跟你回家! 湄洲岛作文350字 关于谦虚的青春励志 水浒传读后感3000字:“仁义”宋江 劳动者的阳光与黑暗 学年第一学期**中学安全工作总结(27) 妇产科工作总结,妇产科护士年终个人工作总结,妇产科医生工作总结,妇产科护理工作总结 初中初三作文650字:读书的乐趣 夏季天热温馨提示短信 保健食品安全管理制度 非主流qq好友分组图案设计╰女人如花╰ 囧╮男人似草 四年的三年 我的爱情很安静 《朝花夕拾》有感作文 夏至是什么意思 谁是知音 公司培训晚会主持词 小学六年级作文600字:千年生死之仙剑奇幻梦五清清的奇特相遇 高考的我们作文 党校培训入党积极分子学习心得体会 加油,永远记住这句话作文 踏入前方的墓地800字 快乐元旦作文700字 第一次漂流 树根和树叶 小学生母亲节国旗下讲话演讲稿 雨中漫步作文1500字 酒店核心竞争力国内相关研究综述 2010高三班主任工作体会总结 【青春励志】--谁的青春不奋斗 好诗大全 水调歌头·雨断翻惊浪 勇军:党风廉政“一票否决”还需后续动作 从乌塔想到的作文300字 望君多珍惜作文300字 时间作文50字 这个世界,本来就没有天长地久 祖国,我为你自豪作文600字

Copyright © 2016 phpStudy |