2011-01-21 89 views
1

我有一个邮件解析器Perl脚本,每次邮件到达用户(使用.qmail)时被调用。它从邮件中提取日历附件,并将文件的“路径”放在使用Directory::Queue module实现的FIFO队列中。Perl IPC - 先进先出和守护进程及CPU使用

读取日历附件的路径并在本地系统以及远程CalDAV服务器上执行某些文件操作的另一个perl脚本正在作为守护进程运行,如解释here所述。所以基本上这个脚本看起来像:

my $declarations 

sub foo { 
. 
. 
} 

sub bar { 
. 
. 
} 

while ($keep_running) { 
    for(keep-checking-the-queue-for-new-entries) { 

     sub caldav_logic1 { 
     . 
     . 
    } 
     sub caldav_logic2 { 
     . 
     . 
    } 
    } 
} 

我正在使用Proc :: Daemon运行脚本作为守护进程。现在的问题是,这个过程几乎有100%的CPU使用率。以更标准,更安全的方式实施守护进程的建议方法是什么?我使用的代码几乎与前面提到的使用Proc :: Daemon的代码相同。

+0

你认为作为一个守护进程运行与它有什么关系?如果您不使用`Proc :: Daemon`运行脚本,它是否使用少于100%的CPU? – mob 2011-01-21 20:02:57

+0

如果不作为守护进程运行,则不会进行连续轮询。作为一个独立的脚本,它只会读取队列中的元素(在给定的状态下通常不会太多),执行操作并退出。 – alcy 2011-01-21 20:07:58

+0

另外,在IRC上,我被建议使用反射/ AnyEvent等来研究基于事件的编程。 – alcy 2011-01-21 20:08:39

回答

3

I打赌它是你的循环和检查新的队列条目。

有几种方法可以查看文件更改的目录。这些方式与操作系统有关,但可能有一个Perl模块将它们包装起来。使用它而不是忙碌循环。即使有睡眠延迟,当您的程序准确告诉OS事件唤醒时,循环效率仍然很低。

File::ChangeNotify看起来很有希望。

1

也许你不希望真正连续的投票。 keep-checking-the-queue-for-new-entries是一个CPU密集的代码部分,即使队列为空时也是如此?这可以解释为什么你的处理器总是很忙。

尝试在while循环的顶部(或非常底部)放置一个sleep 1语句,让处理器在队列检查之间休息。如果这不会降低程序性能太多(例如,如果每个人都可以忍受在公司日历更新之前等待一秒钟)并且CPU使用率仍然很高,请尝试使用sleep 2,sleep 5等。

1
cpan Linux::Inotify2 

内核知道文件何时发生变化并将此信息发送到运行子程序的程序。也许这会更好,因为只有当文件被改变时,程序才会运行子文件。