免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4597 | 回复: 18
打印 上一主题 下一主题

[已解决]perl子程序名可以用变量代替吗 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-13 17:01 |只看该作者 |倒序浏览
本帖最后由 hwcomcn 于 2014-08-14 16:54 编辑

以下的代码我不加strict就不会报错,正常执行,加了strict就报错,中途跳出,错误信息:thread failed to start: Can't use string ("proj_001") as a subroutine ref while "strict refs" in use at thread_02.pl line xxx.
perl子程序名可以用变量代替吗?如何修改?
(必须要加strict,因为程序比较大,需要严格语法检查,下面只是为了举例说明,实际情况有更多的proj_xxx,所以需要用数组来存储子程序名)
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;


  4. my @sublist = ("proj_001","proj_002","proj_003","proj_004","proj_005","proj_006","proj_007","proj_008");

  5. while(@sublist>0)
  6. {
  7.   my $infosub = shift @sublist;
  8.   &$infosub;

  9. }


  10. sub proj_001 {
  11.     print "in sub proj_001","\n";
  12. }
  13. sub proj_002 {
  14.     print "in sub proj_002","\n";
  15. }
  16. sub proj_003 {
  17.     print "in sub proj_003","\n";
  18. }
  19. sub proj_004 {
  20.     print "in sub proj_004","\n";
  21. }
  22. sub proj_005 {
  23.     print "in sub proj_005","\n";
  24. }
  25. sub proj_006 {
  26.     print "in sub proj_006","\n";
  27. }
  28. sub proj_007 {
  29.     print "in sub proj_007","\n";
  30. }
  31. sub proj_008 {
  32.     print "in sub proj_008","\n";
  33. }
复制代码

论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
2 [报告]
发表于 2014-08-13 17:17 |只看该作者
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;


  4. my @sublist = (\&proj_001, \&proj_002, \&proj_003, \&proj_004, \&proj_005, \&proj_006, \&proj_007, \&proj_008);

  5. while(@sublist>0)
  6. {
  7.   my $infosub = shift @sublist;
  8.   $infosub->();

  9. }


  10. sub proj_001 {
  11.     print "in sub proj_001","\n";
  12. }
  13. sub proj_002 {
  14.     print "in sub proj_002","\n";
  15. }
  16. sub proj_003 {
  17.     print "in sub proj_003","\n";
  18. }
  19. sub proj_004 {
  20.     print "in sub proj_004","\n";
  21. }
  22. sub proj_005 {
  23.     print "in sub proj_005","\n";
  24. }
  25. sub proj_006 {
  26.     print "in sub proj_006","\n";
  27. }
  28. sub proj_007 {
  29.     print "in sub proj_007","\n";
  30. }
  31. sub proj_008 {
  32.     print "in sub proj_008","\n";
  33. }
复制代码

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
3 [报告]
发表于 2014-08-13 17:29 |只看该作者
我用过 hash, 数组应该一样吧.

论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
4 [报告]
发表于 2014-08-13 19:17 |只看该作者
貌似这样也行{:3_193:}
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;


  4. my @sublist = ("proj_001","proj_002","proj_003","proj_004","proj_005","proj_006","proj_007","proj_008");

  5. $_ = \&{$_} for @sublist;

  6. while(@sublist>0)
  7. {
  8.   my $infosub = shift @sublist;
  9.   &$infosub;

  10. }


  11. sub proj_001 {
  12.     print "in sub proj_001","\n";
  13. }
  14. sub proj_002 {
  15.     print "in sub proj_002","\n";
  16. }
  17. sub proj_003 {
  18.     print "in sub proj_003","\n";
  19. }
  20. sub proj_004 {
  21.     print "in sub proj_004","\n";
  22. }
  23. sub proj_005 {
  24.     print "in sub proj_005","\n";
  25. }
  26. sub proj_006 {
  27.     print "in sub proj_006","\n";
  28. }
  29. sub proj_007 {
  30.     print "in sub proj_007","\n";
  31. }
  32. sub proj_008 {
  33.     print "in sub proj_008","\n";
  34. }
复制代码

论坛徽章:
26
2015亚冠之胡齐斯坦钢铁
日期:2015-06-25 21:40:202015亚冠之柏斯波利斯
日期:2015-08-31 17:03:192015亚冠之柏斯波利斯
日期:2015-11-07 13:10:00程序设计版块每日发帖之星
日期:2015-11-10 06:20:00每日论坛发贴之星
日期:2015-11-10 06:20:00程序设计版块每日发帖之星
日期:2015-11-26 06:20:00程序设计版块每日发帖之星
日期:2015-12-02 06:20:00黄金圣斗士
日期:2015-12-07 17:57:4615-16赛季CBA联赛之天津
日期:2015-12-23 18:34:14程序设计版块每日发帖之星
日期:2016-01-02 06:20:00程序设计版块每日发帖之星
日期:2016-01-06 06:20:00每日论坛发贴之星
日期:2016-01-06 06:20:00
5 [报告]
发表于 2014-08-13 22:00 |只看该作者
回复 4# stanley_tam

谢谢大神,谢谢
   

论坛徽章:
0
6 [报告]
发表于 2014-08-14 09:17 |只看该作者
本帖最后由 hwcomcn 于 2014-08-14 09:34 编辑

谢谢大神们
2楼,4楼都都正解

但又遇到新问题:
普通数组可以定义成my $xxx : shared (比如我要同时多进程远程登陆多台主机,想并行登陆,还需要进程间共享变量)
普通数组比如
  1. my @sublist : shared = ("proj_001","proj_002","proj_003","proj_004","proj_005","proj_006","proj_007","proj_008");
复制代码
是不会出错的
但是下面的两个若加上shared会报错
  1. #my @sublist = (\&proj_001, \&proj_002, \&proj_003, \&proj_004, \&proj_005, \&proj_006, \&proj_007, \&proj_008);
  2. my @sublist : shared = (\&proj_001, \&proj_002, \&proj_003, \&proj_004, \&proj_005, \&proj_006, \&proj_007, \&proj_008);
复制代码
或者
  1. #my @sublist = ("proj_001","proj_002","proj_003","proj_004","proj_005","proj_006","proj_007","proj_008");
  2. #$_ = \&{$_} for @sublist;
  3. my @sublist : shared = ("proj_001","proj_002","proj_003","proj_004","proj_005","proj_006","proj_007","proj_008");
  4. $_ = \&{$_} for @sublist;
复制代码
贴上代码:
  1. #!/usr/bin/perl
  2. use warnings;
  3. #use strict;
  4. use threads;
  5. use threads::shared;

  6. #my @sublist : shared = (\&proj_001, \&proj_002, \&proj_003, \&proj_004, \&proj_005, \&proj_006, \&proj_007, \&proj_008);
  7. my @sublist  = (\&proj_001, \&proj_002, \&proj_003, \&proj_004, \&proj_005, \&proj_006, \&proj_007, \&proj_008);


  8. my $t1 = threads->create( \&thread_a );
  9. my $t2 = threads->create( \&thread_b );



  10. sub thread_a
  11. {
  12.   while(@sublist>0)
  13.   {
  14.     my $infosub = shift @sublist;
  15.     $infosub->();
  16.     sleep 2;
  17.   }
  18. }

  19. sub thread_b
  20. {
  21.   while(@sublist>0)
  22.   {
  23.     my $infosub = shift @sublist;
  24.     $infosub->();
  25.     sleep 2;
  26.   }
  27. }

  28. $t1->join();
  29. $t2->join();


  30. sub proj_001 {
  31.     print "in sub proj_001","\n";
  32. }
  33. sub proj_002 {
  34.     print "in sub proj_002","\n";
  35. }
  36. sub proj_003 {
  37.     print "in sub proj_003","\n";
  38. }
  39. sub proj_004 {
  40.     print "in sub proj_004","\n";
  41. }
  42. sub proj_005 {
  43.     print "in sub proj_005","\n";
  44. }
  45. sub proj_006 {
  46.     print "in sub proj_006","\n";
  47. }
  48. sub proj_007 {
  49.     print "in sub proj_007","\n";
  50. }
  51. sub proj_008 {
  52.     print "in sub proj_008","\n";
  53. }
复制代码
第7行和第8行的注释换一下就报错
想要的结果是每个进程执行一遍,不是执行2遍

论坛徽章:
0
7 [报告]
发表于 2014-08-14 09:17 |只看该作者
本帖最后由 hwcomcn 于 2014-08-14 09:32 编辑

不好意思,可能浏览器多刷新一次,多发了一个回帖,见6楼

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
8 [报告]
发表于 2014-08-14 12:02 |只看该作者
threads::shared 文档中说只能 share 简单的 scalar(应该就数字和字符串) array hash 及它们的引用,函数引用是不可以的。

你还是用多进程模型吧

论坛徽章:
0
9 [报告]
发表于 2014-08-14 16:53 |只看该作者
好。我开始学习下perl的多线程。大骆驼的16,17章是讲这个的。

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
10 [报告]
发表于 2014-08-15 08:37 |只看该作者
楼主能说明一下你要在多台主机上做什么事么? 非要并行这么严格?

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP