use strict;
use threads;
use threads::shared;
my $MAXTHREAEDNUM = 20;
my $CURTHREADNUM :shared = 0;
my @threads;
sub startThread
{
## 当前新建的线程数加一:
{
lock($CURTHREADNUM);
$CURTHREADNUM++;
}
print"here is the $CURTHREADNUM thread!n";
sleep(3);
## 当前活动的线程数减一:
{
lock($CURTHREADNUM);
$CURTHREADNUM--;
}
}
{
my $threadid;#壹
for(my $i=0;$i<5;$i++)
{
while(1)
{
if ( $CURTHREADNUM < $MAXTHREAEDNUM)
{
$threadid = threads->create('startThread');
# my $threadid = threads->create('startThread'); #贰
if ( $threadid < 0 )
{
print "To Create Thread Error,Please sleep 30's,Try Again n";
}
push(@threads, $threadid);
last;
}
else
{
print "The max thread num limit, waiting 1 second,Try Again. n" ;
sleep(1);
}
}
}
my $i=0;
foreach my $thread (@threads)
{
$i++;
print "Begin to join $i: ".$thread."n";
$$thread->join();
}
}
######################################################################
# program section
open(STDERR, ">&STDOUT");
print "进程号PID:$$ n";
exit(main());
定义壹运行日志如下:
---------------------------------------------
进程号PID:1660
Begin to join 1: REF(0x18a66a0)
here is the 1 thread!
here is the 2 thread!
here is the 3 thread!
here is the 4 thread!
here is the 5 thread!
Begin to join 2: REF(0x18a66a0)
Thread already joined at thread_test.pl line 58.
-------------------------------------------------------
可以看出 join 1和join 2的$thread值是一样的,即REF(0x18a66a0),也就是说REF(0x18a66a0)线程在1处做了join后,2处试图再做一次。
Thread already joined at thread_test.pl line 58.错误就可以理解了。
为什么数组@threads中的值是唯一的呢?(把上述脚本 $$thread->join();去掉,可以看出@threads中各元素值均相同)
在线程创建后,即 $threadid = threads->create('startThread');返回的为1对象,定义外部变量时,只会改变变量值,不会改变其地址,
所以printer $threadid 将会为一常量值(第一个返回对象的地址),如下示:
----------------------------------------------------
进程号PID:3288
The created theadid:REF(0x18a66b8)
The created theadid:REF(0x18a66b8)
here is the 1 thread!
here is the 2 thread!
The created theadid:REF(0x18a66b8)
The created theadid:REF(0x18a66b8)
here is the 3 thread!
here is the 4 thread!
here is the 5 thread!
The created theadid:REF(0x18a66b8)
---------------------------------------------------
但printer $threadid会有变化,如下示:
----------------------------------------------------
The created theadid:threads=SCALAR(0x18a7024)
The created theadid:threads=SCALAR(0x18a703c)
here is the 1 thread!
here is the 2 thread!
The created theadid:threads=SCALAR(0x18a7054)
The created theadid:threads=SCALAR(0x18a706c)
here is the 3 thread!
here is the 4 thread!
here is the 5 thread!
The created theadid:threads=SCALAR(0x1a9bc78)
----------------------------------------------------
push(@threads, $threadid);
$threadid为threads->create('startThread');的返回对象,将对象加入数组需要加上"",即为$threadid;
上述语句若改成push(@threads, $threadid);join将会报错:Can't call method "join" without a package or object reference at ...
若将定义改为贰:
运行正常,结果日志如下:
------------------------------------------------------------
进程号PID:2988
here is the 1 thread!
Begin to join 1: REF(0x18a66b8)
here is the 2 thread!
here is the 3 thread!
here is the 4 thread!
here is the 5 thread!
Begin to join 2: REF(0x275e24)
Begin to join 3: REF(0x18a6b8c)
Begin to join 4: REF(0x18a6bb0)
Begin to join 5: REF(0x18a6bd4)
-----------------------------------------------------------
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16723161/viewspace-1023254/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/16723161/viewspace-1023254/
本文介绍了一个Perl脚本中关于线程管理和同步的问题案例。通过控制并发线程的数量,并确保线程安全地进行创建和结束,文章详细分析了线程ID的正确使用方式以及如何避免重复join同一线程的问题。
4960

被折叠的 条评论
为什么被折叠?



