免费注册 查看新帖 |

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
11 [报告]
发表于 2009-07-01 14:31 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 14:23 发表



请看这里:
http://perldoc.perl.org/Thread.html

Thread 和 threads 是两套不同的线程实现,现在已经不鼓励用 Thread 了。更为离奇的是,你使用了 use threads; 但却在其中用 Thread 中的函数。

论坛徽章:
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
12 [报告]
发表于 2009-07-01 15:12 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 14:50 发表
看来是我是混淆了这两个模块,经过修改后是这样,但是还是run out of memory.
my %thread_hash = ();
my $current_thread = 0;
for(0..2000)
{
         if( $current_thread >= 10 )
         {
                 foreach my $thread(keys %thread_hash )
                 {
                        if($thread->is_joinable())
                                {
                                        $thread->join( );
                                        delete $thread_hash{$thread};
                                }else{
                                        next;
                                }
                 }
         }else{
                $thread_hash{$_} = threads->create(\&prt);
        }
}

你有仔细想过这段代码的逻辑么?例如说 %thread_hash 的 key 是 thread object 么?$current_thread 会增加么?

论坛徽章:
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
13 [报告]
发表于 2009-07-01 17:46 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 16:26 发表
改成这个样子是可以的,每次起10个thread,但是每次都要等这10个完成才能起下一轮的10个,有没有更好的办法了。

问题就出在这里

  1.                 foreach my $t (keys %thrs){
  2.                                 $thrs{$t}->join();
  3.                                 delete $thrs{$t};
  4.                 }
复制代码

在 join 之前,你应该先用 is_joinable 判断下是否能 join,不能的就忽略。另外,也可以考虑直接用 threads->list(threads::joinable) 获取可以 join 的线程的列表,不过这个功能 Perl 5.8.8 没有,Perl 5.10.0 新增加的。

另外如果每次起得太多,对performance影响会比较大,如何确定同时起多少个比较合适. 谢谢!

这个要你自己估计了。

论坛徽章:
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
14 [报告]
发表于 2009-07-01 18:13 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 18:00 发表
对的,以前也是这么设计的,但是得到这个错误:Can't locate object method "is_joinable" via package "threads" at thread1.pl.bak line 23.
perl的版本是,
bash-3.2# perl -v

This is perl, v5.8.8 bu ...

Perl 5.8.8 是没有 is_joinable 的。不过你可以用父子线程共享的线程个数计数器来控制子线程数量,然后在线程创建后,将其 detach 掉。

或者,你也可以将 Perl 升级到 5.10.0

[ 本帖最后由 MMMIX 于 2009-7-1 18:14 编辑 ]

论坛徽章:
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
15 [报告]
发表于 2009-07-01 20:56 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 19:28 发表
这样好像不行了,好像是加锁的原因,帮忙看看怎么处理?

这是我写的:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. use threads;
  5. use threads::shared;

  6. my $thread_num :shared = 0;

  7. sub start_thread {
  8.         print "Thread ", threads->tid(), " started, current thread numbers $_[0]\n";
  9.         {
  10.                 lock($thread_num);
  11.                 $thread_num--;

  12.                 cond_signal($thread_num);
  13.         }
  14. }

  15. for (1 .. 200) {
  16.         {
  17.                 lock($thread_num);
  18.                 cond_wait($thread_num) until $thread_num < 10;

  19.                 my $t = threads->create(\&start_thread, $thread_num + 1);
  20.                 $t->detach();
  21.                
  22.                 $thread_num++;
  23.         }
  24. }
复制代码


很奇怪的是,启动的线程的总数并不是 200 个。

使用 is_joinable 的例子:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. use threads;

  5. my $thread_num = 0;

  6. sub start_thread {
  7.         print "Thread ", threads->tid(), " started, current thread number $_[0]\n";
  8. }

  9. for (1 .. 200) {
  10.         if ($thread_num >= 10) {
  11.                 for my $t (threads->list(threads::joinable)) {
  12.                         $t->join();
  13.                         $thread_num--;
  14.                 }
  15.                 redo;
  16.         }

  17.         threads->create(\&start_thread, $thread_num + 1);
  18.         $thread_num++;
  19. }

  20. for my $t (threads->list()) {
  21.         $t->join();
  22. }
复制代码

[ 本帖最后由 MMMIX 于 2009-7-1 21:09 编辑 ]

论坛徽章:
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
16 [报告]
发表于 2009-07-01 21:19 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 21:16 发表
我这样可以,

可以什么?

BTW,用 sleep 同步线程/进程是不可靠的。

论坛徽章:
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
17 [报告]
发表于 2009-07-01 21:29 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 21:20 发表
就是说我的这个程序运行后是101个线程,去掉sleep也是可以的

但你那个是不正确的,对共享资源的访问应该加锁。

我把你那个去掉 sleep 运行了多次,结果各次创建的子线程的总数并不相同。

[ 本帖最后由 MMMIX 于 2009-7-1 21:34 编辑 ]

论坛徽章:
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
18 [报告]
发表于 2009-07-01 21:30 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 21:16 发表
你的那个is_joinable的可以吗?

那个没有问题。

论坛徽章:
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
19 [报告]
发表于 2009-07-01 21:36 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 21:31 发表
但是加锁的话要等待这个&prt完了才可以做下一个,那就失去了多线程的意义啦. 还是相当于一个一个执行

你难道没有看到我上面的例子么?在线程函数中,只需要在退出的时候才需要对 $thread_num 加锁并将其减一。

论坛徽章:
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
20 [报告]
发表于 2009-07-01 21:39 |显示全部楼层
原帖由 Perl_Er 于 2009-7-1 21:37 发表
有时候是100个,有时候是101,100个左右是吗?

还有 99 个,98 个,等等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP