免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Perl_Er

关于perl的多线程&多进程的问题 [复制链接]

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2009-06-30 15:29 |显示全部楼层
原帖由 Perl_Er 于 2009-6-30 12:34 发表
我在HPUX上运行OVO,然后被管理的节点有大约3000台,我需要在管理机上每5分钟对所有被管节点进行ping的操作,看这个节点是否是UP的,如果是UP的自然就不管了,如果是down了的,则需要发alert到OVO管理机。需要同时对多个节点并行操作。否则5分钟运行不完。

你是通过什么方式 ping 的?直接调用外部的 ping 还是使用 Perl 提供的模板?如果是前者,给 ping 传了什么参数?有没有多余的时间消耗?调用外部程序本身的时间消耗考虑了么?

任务在线程之间如何划分的?是每个线程负责一部分机器,还是一个线程处理完一个任务再从总的任务列表中领新的任务(也即线程/进程池的方式)?如果是前者,如何控制 ping 不通导致的超时问题?
之前有用过多线程,但是偶尔会crash,所以这次选择多进程

查过什么原因导致 crash 么?是 Perl 的线程实现还是使用方面的问题?

论坛徽章:
0
发表于 2009-06-30 16:52 |显示全部楼层
你是通过什么方式 ping 的?直接调用外部的 ping 还是使用 Perl 提供的模板?如果是前者,给 ping 传了什么参数?有没有多余的时间消耗?调用外部程序本身的时间消耗考虑了么?

是通过perl的Net:ing模块ping的

任务在线程之间如何划分的?是每个线程负责一部分机器,还是一个线程处理完一个任务再从总的任务列表中领新的任务(也即线程/进程池的方式)?如果是前者,如何控制 ping 不通导致的超时问题?

是用的线程池(现在用进程池),控制线程(进程)在100个以内

查过什么原因导致 crash 么?是 Perl 的线程实现还是使用方面的问题?


多线程的:
------------------------------------
my $current_thread = 0;
my $max_thread = 100;
foreach( @hosts )
{
         if( $current_thread >= $max_thread )
         {
                 foreach my $thread( @thread_array )
                 {
                         $thread -> join( );
                 }

                 $current_thread = 0;
         }
         $thread_array[$current_thread] = threads -> new( \&ingHost, $host );
         $current_thread ++;
}


多进程的:
------------------------------------
for (@all_nodes) {
    wait_for_a_kid() if keys %pid_to_host > $maxprocesses;
    if (my $pid = fork) {
        ## parent does...
        $pid_to_host{$pid} = $_;
    }
    else { # child does
        ## child does...
        ping_a_host($_);
        exit 1;
    }
}

[ 本帖最后由 Perl_Er 于 2009-6-30 16:54 编辑 ]

论坛徽章:
0
发表于 2009-06-30 17:33 |显示全部楼层
那你换一个其他操作,比如只有一个echo ,把最大值调到200,看下会不会CRASH,估计不是多线程的问题

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2009-06-30 17:52 |显示全部楼层
原帖由 Perl_Er 于 2009-6-30 16:52 发表
多线程的:
------------------------------------
my $current_thread = 0;
my $max_thread = 100;
foreach( @hosts )
{
         if( $current_thread >= $max_thread )
         {
                 foreach my $thread( @thread_array )
                 {
                         $thread -> join( );
                 }

                 $current_thread = 0;
         }
         $thread_array[$current_thread] = threads -> new( \&ingHost, $host );
         $current_thread ++;
}

你这个并不能充分的并行。应该在父子线程中共享计数器 $max_thread (通过 threads::shared),然后在创建线程后 $max_thread 加一,线程退出时 $max_thread 减一,操作 $max_thread 时注意加锁同步。

多进程的:
------------------------------------
for (@all_nodes) {
    wait_for_a_kid() if keys %pid_to_host > $maxprocesses;
    if (my $pid = fork) {
        ## parent does...
        $pid_to_host{$pid} = $_;
    }
    else { # child does
        ## child does...
        ping_a_host($_);
        exit 1;
    }
}

应该在每次循环的时候 wait, 这样可以避免僵尸进程的积累。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2009-06-30 19:42 |显示全部楼层
原帖由 Perl_Er 于 2009-6-30 16:52 发表
是用的线程池(现在用进程池),控制线程(进程)在100个以内

BTW,你下面给的这个算不得线程池,因为在线程池中,线程在处理完一个任务后,并不退出,而是直接接受并继续处理下一个任务。只有在所有任务都已经处理完的情况下,线程才可能退出。

论坛徽章:
0
发表于 2009-06-30 20:19 |显示全部楼层
应该在每次循环的时候 wait, 这样可以避免僵尸进程的积累。

用这个多进程还是没有问题的,我在下面还有个函数用来wait所有的进程。没有贴出来,也就是函数:wait_for_a_kid()  ,看来线程好像没有进程好控制

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2009-06-30 21:51 |显示全部楼层
原帖由 Perl_Er 于 2009-6-30 20:19 发表

用这个多进程还是没有问题的,我在下面还有个函数用来wait所有的进程。没有贴出来,也就是函数:wait_for_a_kid()  ,

你说的 wait_for_a_kid 我看到了,也猜到了意思。但是,在当前进程个数小于 $maxprocesses 的时候,你并不 wait,那么前边已经结束的子进程,就会处于僵尸状态,而这些僵尸子进程的数量会积累。

看来线程好像没有进程好控制

不见得。各有各的优缺点。

论坛徽章:
0
发表于 2009-06-30 22:25 |显示全部楼层

回复 #17 MMMIX 的帖子

对,就算累计应该也不会大于$maxprocesses吧。应为我在整个程序下面还有一个wait_for_a_kid 来结束没有wait的子进程
for (@all_nodes) {
    wait_for_a_kid() if keys %pid_to_host > $maxprocesses;
    if (my $pid = fork) {
        ## parent does...
        $pid_to_host{$pid} = $_;
    }
    else { # child does
        ## child does...
        ping_a_host($_);
        exit 1;
    }
}

#reap all childs
###############################################################################
1 while wait_for_a_kid();

论坛徽章:
0
发表于 2009-06-30 22:28 |显示全部楼层
测试了一下,运行这个简单的程序会"out  of memory"
#!/usr/bin/perl
use threads;
use strict;

sub prt(){
        print "hello\n";
}


my %thread_hash = ();
my $current_thread = 0;
for(0..10000)
{
         if( $current_thread >= 10 )
         {
                 foreach my $thread(keys %thread_hash )
                 {
                        if($thread->done())
                                {
                                        $thread -> join( );
                                        delete $thread_hash{$thread};
                                }else{
                                        next;
                                }
                 }
         }else{
                $thread_hash{$_} = threads -> new( \&prt );
        }
}

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2009-07-01 08:26 |显示全部楼层
原帖由 Perl_Er 于 2009-6-30 22:25 发表
对,就算累计应该也不会大于$maxprocesses吧。应为我在整个程序下面还有一个wait_for_a_kid 来结束没有wait的子进程

没错。如果退出这个循环后,你的脚本就结束了,那么最后的 wait_for_a_kid 是没有必要的。BTW,如果wait_for_a_kid 会 wait 所有已经结束的进程,那么它的名字就起的很不合适。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP