2013-07-19 176 views
3

我有一個perl腳本,它執行一些mysql連接來觸發選擇查詢。 我使用DBI perl模塊來做同樣的事情。Perl腳本消耗100%cpu

有時它會消耗100%cpu並且什麼也不做。我得到了gdb對現場流程的回溯,同時它消耗了99%到100%的cpu。

#0 0x0000003990a7c680 in memcpy() from /lib64/libc.so.6 
#1 0x0000003992ae6e27 in Perl_regexec_flags() from /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE/libperl.so 
#2 0x0000003992a922d5 in Perl_pp_subst() from /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE/libperl.so 
#3 0x0000003992a8a39e in Perl_runops_standard() from /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE/libperl.so 
#4 0x0000003992a37ecc in perl_run() from /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE/libperl.so 
#5 0x00000000004017bc in main() 

我該怎麼辦? (我正在使用CentOS版本5.8(最終)kernel-2.6.18-308.el5)

+1

它看起來像它的處理正則表達式。像http://search.cpan.org/~jjore/App-Stacktrace-0.08/bin/perl-stacktrace這樣的東西可以告訴你在Perl代碼中它被卡住了嗎? –

+4

那麼,你仔細看看你的代碼,可能會搜索綁定到非常大的數據或者可能會非常糟糕地回溯的''/''替換。正常的回溯信號太低而不能提供有用的數據(這裏只告訴我們哪個運行正在運行)。 – amon

+2

請包含正在執行的代碼,尤其是正則表達式。 – JDB

回答

1

有時正則表達式處理可能需要一個永遠的時間,即使是中等數量的數據。

讓說你有一個正則表達式是這樣的:

my $data =~ s!.*findit:(.+)!$1!gis; 

這正則表達式做同樣的,但它的速度要快得多:

my $data =~ s!\A.*findit:(.+)\z!$1!is; 
+0

*「有時正則表達式處理可能會永遠」*錯誤:我想回想一下,在50個不消耗字符的操作之後,Perl正則表達式引擎會中止。而且,除了通過回溯之外,字符串中的位置不能減小。因此,每個正則表達式都會終止。然而,正則表達式可以用過度回溯的方式來編寫(例如,使用許多'?'量詞或者貪婪匹配)。你的例子沒有證明這一點,如果你想避免不必要的捕獲,可以寫成's/\ A。*(?i:findit):(?=。)// s'。 – amon

+0

thnx user1126070,它非常有用。 – JohnG

+0

我在製作腳本中遇到了這個問題,至少在過去的幾年前(5.8早,5.6晚) – user1126070