小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

perl 語言編程實(shí)例-多進(jìn)程篇...

 weicat 2007-04-25

perl 語言編程實(shí)例-多進(jìn)程篇


創(chuàng)建:2005-10-27 22:03:38
作者:Unlinux
來自: http://www.Unlinux.com

作者:horsley

perl 語言編程實(shí)例-多進(jìn)程篇

perl 語言是一種非常強(qiáng)大的腳本語言,其應(yīng)用遍及系統(tǒng)維護(hù),CGI,數(shù)據(jù)庫編程。
以下是我遇到的一個(gè)具體問題,應(yīng)用perl獲得圓滿解決。

問題提出:
某數(shù)據(jù)庫應(yīng)用。需要檢索一批數(shù)據(jù)(A表,數(shù)據(jù)量12萬左右)。對(duì)該批數(shù)據(jù)
將進(jìn)行逐一核對(duì),期間將關(guān)聯(lián)三個(gè)千萬級(jí)的表(C,D,E表,分別有近億條數(shù)據(jù)),
并將檢索狀態(tài)插入一張新表(F)。

傳統(tǒng)解決方案:
編寫存儲(chǔ)過程。打開一個(gè)cursor,對(duì)A表遍歷,逐一檢索C,D,E表。
判斷狀態(tài)寫入新表。編程過程十分簡單,順利完成。但執(zhí)行時(shí)效率低下,耗時(shí)在
8小時(shí)左右,不能滿足要求。

分析:
C,D,E表建有極其完備的索引。對(duì)單條數(shù)據(jù)檢索極其快速。同時(shí)執(zhí)行時(shí)主機(jī)CPU

,
內(nèi)存等資源十分空閑。查詢單條記錄耗時(shí):8×3600/12萬=0.24秒,也是在合理的

范圍。
同時(shí)主機(jī)數(shù)據(jù)庫在業(yè)務(wù)高峰期時(shí)可以支持500-600用戶同時(shí)登陸(telnet方式)。

以上
說明性能瓶頸不在主機(jī),數(shù)據(jù)庫上。

結(jié)論:以上所有都合情合理,采用單進(jìn)程方式無法進(jìn)一步提高性能。為提高速度,

只能
采用多進(jìn)程。


快速構(gòu)造原型:

原型一:
#!/usr/bin/perl

my $maxchild=20;
foreach $item (1..500) {
while ( `ps -ef|grep $0|wc -l` > $maxchild) { select undef,undef,undef,0.1; };
if ($PID=fork()){
print "Starting Sub_Process:$PIDn";
} else {
print "I will handle data:$itemn";
sleep 1;
exit 1;
};
}

執(zhí)行以上,正常,子進(jìn)程控制在20。

以上述腳本為基礎(chǔ),添加數(shù)據(jù)庫部分:

#!/usr/bin/perl

use DBI;


my $dbh=DBI->connect(...);
my $sth=$dbh->prepare(qq/select * from A/);
$sth->execute();
$sth->bind_column(undef,.....);

while ($sth->fetch()) {
while ( `ps -ef|grep $0|wc -l` > $maxchild) { select undef,undef,undef,0.1; };
if ($PID=fork()) {
print "Starting Sub_Process:$PIDn";
} else {
query(B,C,D); #執(zhí)行數(shù)據(jù)庫操作
insert(E);
exit 1;
}
}
$sth->finish();
$dbh->disconnect();

確保無語法錯(cuò)誤,執(zhí)行。處理一兩條數(shù)據(jù)后腳本報(bào)錯(cuò),中斷。具體錯(cuò)誤略。

分析:程序框架沒錯(cuò),但是在fork子進(jìn)程時(shí),$dbh同時(shí)被子進(jìn)程繼承,導(dǎo)致該數(shù)據(jù)

庫連接反復(fù)使用。
由于數(shù)據(jù)庫底層的某種原因,對(duì)該種操作是不允許的。結(jié)論:以上簡單的多進(jìn)程方

式不可行。數(shù)據(jù)庫
連接部分必須同 fork 分離。

######################################

考慮很久,設(shè)計(jì)如下原型:將打開A表的cursor單獨(dú)提出,結(jié)果傳給另外一個(gè)進(jìn)程


12萬數(shù)據(jù)較大,作為參數(shù)傳遞似乎不妥,考慮利用管道通信。



原型二:
############################

分成 getdata,setdata兩個(gè)程序。首先建立管道 : mknod data.pipe p

cat getdata:

#!/usr/bin/perl

use DBI;
open(DATAPIPE,">./data.pipe") or die "$!n";

my $dbh=DBI->connect(...);
my $sth=$dbh->prepare(qq/select * from A/);
$sth->execute();
$sth->bind_column(undef,.....);

while ($sth->fetch()) {
print DATAPIPE data.....;
}
close(DATAPIPE);

######################

cat setdata:

#!/usr/bin/perl
use DBI;
open(DATAPIPE,"<./data.pipe") or die "$!n";

my $pipecount=0;
my $maxlines=2000;
my @lines=();

while($record=<DATAPIPE>) {
$pipecount++;
push @lines,$record;

unless ($pipecount % $maxlines) {
if ($PID=fork()){
print "Starting Sub_Process:$PIDn";
@lines=();
}else{
my $dbh=DBI->connect(...);
foreach (@lines) {
handle_data($_);
}
$dbh->disconnect();
exit 1;
}
}
}

my $dbh=DBI->connect(...);
foreach (@lines) {
handle_data($_);
}

$dbh->disconnect();

以上腳本運(yùn)行正常,執(zhí)行時(shí)啟動(dòng):12萬/$maxlines= 60個(gè)子進(jìn)程。
處理完所有數(shù)據(jù)耗時(shí)在 10分鐘左右,效率提高幾十倍。

腳本執(zhí)行方式:./getdata&./setdata

轉(zhuǎn)載自:http://www./doc/perl/20051027/4153.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多