2011-01-21 92 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 

內核知道文件何時發生變化並將此信息發送到運行子程序的程序。也許這會更好,因爲只有當文件被改變時,程序纔會運行子文件。