Thread already joined at **

miguelmin發表於2009-06-18

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--;
}
}

[@more@]sub main
{
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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章