分享
 
 
 

perl语言编程实例-多进程篇

王朝perl·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

作者:horsley

perl 语言编程实例-多进程篇

perl 语言是一种非常强大的脚本语言,其应用遍及系统维护,CGI,数据库编程。

以下是我遇到的一个具体问题,应用perl获得圆满解决。

问题提出:

某数据库应用。需要检索一批数据(A表,数据量12万左右)。对该批数据

将进行逐一核对,期间将关联三个千万级的表(C,D,E表,分别有近亿条数据),

并将检索状态插入一张新表(F)。

传统解决方案:

编写存储过程。打开一个cursor,对A表遍历,逐一检索C,D,E表。

判断状态写入新表。编程过程十分简单,顺利完成。但执行时效率低下,耗时在

8小时左右,不能满足要求。

分析:

C,D,E表建有极其完备的索引。对单条数据检索极其快速。同时执行时主机CPU

内存等资源十分空闲。查询单条记录耗时:8×3600/12万=0.24秒,也是在合理的

范围。

同时主机数据库在业务高峰期时可以支持500-600用户同时登陆(telnet方式)。

以上

说明性能瓶颈不在主机,数据库上。

结论:以上所有都合情合理,采用单进程方式无法进一步提高性能。为提高速度,

只能

采用多进程。

快速构造原型:

原型一:

#!/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:$PID\n";

} else {

print "I will handle data:$item\n";

sleep 1;

exit 1;

};

}

执行以上,正常,子进程控制在20。

以上述脚本为基础,添加数据库部分:

#!/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:$PID\n";

} else {

query(B,C,D); #执行数据库操作

insert(E);

exit 1;

}

}

$sth->finish();

$dbh->disconnect();

确保无语法错误,执行。处理一两条数据后脚本报错,中断。具体错误略。

分析:程序框架没错,但是在fork子进程时,$dbh同时被子进程继承,导致该数据

库连接反复使用。

由于数据库底层的某种原因,对该种操作是不允许的。结论:以上简单的多进程方

式不可行。数据库

连接部分必须同 fork 分离。

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

考虑很久,设计如下原型:将打开A表的cursor单独提出,结果传给另外一个进程

12万数据较大,作为参数传递似乎不妥,考虑利用管道通信。

原型二:

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

分成 getdata,setdata两个程序。首先建立管道 : 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:$PID\n";

@lines=();

}else{

my $dbh=DBI->connect(...);

foreach (@lines) {

handle_data($_);

}

$dbh->disconnect();

exit 1;

}

}

}

my $dbh=DBI->connect(...);

foreach (@lines) {

handle_data($_);

}

$dbh->disconnect();

以上脚本运行正常,执行时启动:12万/$maxlines= 60个子进程。

处理完所有数据耗时在 10分钟左右,效率提高几十倍。

脚本执行方式:./getdata&./setdata

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有