Perlã§ã¹ã¬ããå¦çãè¡ããµã³ãã«å°ã
ã¯ããã«
Hatena::Bookmark::24hã®HTMLãã¼ã¿ãçæããéã«ã¯ã¦ãªããã¯ãã¼ã¯ã®åå¥ãã¼ã¸RSSãè¤æ°ä»¶åå¾ããããã§ãããåå¾å¦çãå¢ãã§ä½ã£ã¦ãã¾ã£ãããã«ã¹ã¬ããåããã¦ããªãã£ãããã¾ãã
æ©ã話ãï¼ä»¶ç®ã®RSSåå¾âå®äºâ解æâï¼ä»¶ç®ã®RSSåå¾ââ¦ã®ããã«ç´ååä½ããã¦ãã¾ã£ã¦ããç¶æ³ã§ããããã¯å¹çæªããã§ãã
並åã§è¤æ°ã®RSSãåå¾ã§ããã°å¦çæéã®ç縮ã«ãªãããã§ãããã¡ãªã¿ã«Perlã«ã¯ä¸¦ååä½ãè¡ãä»çµã¿ã¨ãã¦ã¹ã¬ãããçµã¿è¾¼ã¾ãã¦ããããã§ãä»æ¥ã¯Perlã§ã¹ã¬ããå¦çãè¡ãããã®å¦çãã¡ã¢ãã¦ããããã¨æãã¾ãã
注æ
å®é¨ããç°å¢ã¯Windows XP(SP3)/ActivePerl 5.8.8(Build819)ã§ãããã以å¤ã®ç°å¢ã§ã¯åä½ç¢ºèªãã¦ãã¾ããã
ãµã³ãã«ï¼ï¼ã¹ã¬ããçæï¼å®è¡
æ¦è¦
ã¹ã¬ãããè¤æ°åçæã»é å(@threads)ã«æ ¼ç´ãã¦åã¹ã¬ãããä¸æ°ã«å®è¡(join)ãã
使ã£ã¦ããã¡ã½ãã
threads->new():ã¹ã¬ãããçæããã第ï¼å¼æ°ã¯ãã®ã¹ã¬ããå
ã§åä½ãããé¢æ°ãã第ï¼å¼æ°ä»¥éã¯ç¬¬ï¼å¼æ°ã§æå®ããé¢æ°ã«ããããã©ã¡ã¼ã¿ã¨ãªãã¾ãã
join:ã¹ã¬ãããå®è¡ãã¾ãã
threads->yield():ã¹ã¬ããã®å®è¡æ¨©ãå¥ã®ã¹ã¬ããã«æ¸¡ãã¾ãã
ã½ã¼ã¹ã³ã¼ã
use strict; use threads; my @threads; print "Create threads\n"; foreach (1 .. 5){ my $thread = threads->new(\&my_thread, $_); push(@threads, $thread); } print "Join threads \n"; foreach(@threads){ my ($return) = $_->join; print "$return closed\n"; } # ã¹ã¬ããã®å¦ç sub my_thread { my $i = shift; foreach (1 .. 3){ print "Thread $i($_)\n"; threads->yield(); sleep 1; } return ($i); }
å®è¡çµæ
Create threads Thread 1(1) Thread 2(1) Thread 3(1) Thread 4(1) Join threads Thread 5(1) Thread 3(2) Thread 1(2) Thread 2(2) Thread 5(2) Thread 4(2) Thread 1(3) Thread 2(3) Thread 3(3) Thread 5(3) Thread 4(3) 1 closed 2 closed 3 closed 4 closed 5 closed
åã¹ã¬ãããããããããåä½ãã¦ããã¨ããæããããããã¨æãã¾ãã
ãªãsleepãå¿ è¦ãªã®ãããã¾ãã¡ããããªã
threads->yield(); sleep 1;
ãã®é¨åãyieldã§æ¬¡ã®ã¹ã¬ããã«ç§»è¡ããã¨æã£ããã ãã©ãyieldãã³ã¡ã³ãã¢ã¦ããã¦sleepã®ã¿ã§ãã¹ã¬ãã移è¡ãè¡ãããããã¼ãã
threads->yield()ãè¡ããªãå ´åã®å®è¡çµæ
ã¡ãªã¿ã«ãsleepãã³ã¡ã³ãã¢ã¦ããããã©ããªããã
Create threads Thread 1(1) Thread 1(2) Thread 1(3) Thread 2(1) Thread 2(2) Thread 2(3) Thread 3(1) Thread 3(2) Thread 3(3) Thread 4(1) Thread 4(2) Thread 4(3) Join threads Thread 5(1) Thread 5(2) Thread 5(3) 1 closed 2 closed 3 closed 4 closed 5 closed
åã¹ã¬ããèªåã®ä»äºãçµãããªãéãå¥ã®ã¹ã¬ããã«å®è¡æ¨©ã渡ãã¦ãªãï¼ã®ããªï¼ãã®éãã¯èå³æ·±ãã§ããã
å®è¡ã®ã¿ã¤ãã³ã°ã¨ãåã¹ã¬ãããã©ã®ããã«åä½ãã¦ãããçã詳細ã«ç¢ºèªãã¦ã¿ããã¨ããã§ãã
ãµã³ãã«ï¼ï¼ã¹ã¬ããéã§å¤æ°ãå ±æãã(ãã¾ãããä¾ã§ã¯ãªã)
æ¦è¦
ã¹ã¬ããå ã§ä½¿ç¨ããå¤æ°ã¯åºæ¬çã«ã¯ãã¼ã«ã«(ãã®ã¹ã¬ããã®ã¿ã§æå¹)ã§ããåã¹ã¬ããã§å ±æãããå¤æ°ã«ã¯sharedãã¤ãã¾ãã
ã½ã¼ã¹ã³ã¼ã
use strict; use threads; use threads::shared; my $data : shared; my @threads; print "Create threads\n"; foreach (1 .. 5){ my $thread = threads->new(\&my_thread, $_); push(@threads, $thread); } print "Join threads \n"; foreach(@threads){ my ($return) = $_->join; print "$return closed\n"; } # ã¹ã¬ããã®å¦ç sub my_thread { my $i = shift; foreach(1 .. 20){ $data++; print "Thread $i b($data)\n"; sleep 1; # âã¨âã§$dataã®åºåãå¤ãããã¨ããããã¨ã«æ³¨æ # ã¿ã¤ãã³ã°ã«ãã£ã¦ã¯ãã®ã¹ã¬ããã®æå³ããªãå¤ã«ãªã£ã¦ããã¨ãããããã print "Thread $i a($data)\n"; threads->yield(); } return ($i); }
å®è¡çµæ
Create threads Thread 1 b(1) Thread 2 b(2) Thread 3 b(3) Thread 4 b(4) Join threads Thread 5 b(5) Thread 2 a(5) Thread 1 a(5) Thread 2 b(6) Thread 1 b(7) Thread 4 a(7) Thread 3 a(7) Thread 4 b(8) * âãããã Thread 3 b(9) Thread 5 a(9) Thread 5 b(10) Thread 2 a(10) Thread 1 a(10) Thread 2 b(11) Thread 1 b(12) Thread 4 a(12) * âããã¾ã§ã®éã« Thread 3 a(12) ä»ã®ã¹ã¬ãããå ±éå¤æ°ãããããåãã¦ãããã¨ã«æ³¨æ Thread 4 b(13) Thread 3 b(14) Thread 5 a(14) Thread 5 b(15) Thread 2 a(15) Thread 1 a(15) Thread 2 b(16) (以ä¸ç¥)
ã³ã¡ã³ãã§ãæ¸ãã¾ãããèªã¹ã¬ãããåä½ä¸ã«ä»ã¹ã¬ãããå¤ãå¤æ´ãããã¨ãããã®ã§æ³¨æã
ãµã³ãã«ï¼ï¼ã»ããã©ãå©ç¨ãã¦ä»ã®ã¹ã¬ãããä»å ¥ããªãããã«å¶å¾¡ãã
æ¦è¦
Semaphore(ã»ããã©)ã使ç¨ãã¦å¤æ°$dataãåç
§ãã¦ããéã¯ä»ã®ã¹ã¬ãããå²ãè¾¼ãã§ããªãããã«ããä¾ã
ã»ããã©ã¯ãã¯ããã®ãããªãã®ã§newæã«åæ°ã決ãããã¾ã(è³æºæ°ã¨å¼ã³ã¾ã)ãdownã¡ã½ããã§1æ¸ãããupã¡ã½ããã§1å¢ããã¾ãã
è³æºæ°ãï¼ã«ãªã£ãç¶æ
ã§downãè¡ã£ãå ´åãdownãè¡ããç¶æ
ã«ãªãã¾ã§(ã¤ã¾ã誰ããupããã¾ã§)å¾
ã¡ç¶ãã¾ã(downã¡ã½ããããæãåºãªã)ã
以ä¸ã®ã½ã¼ã¹ã³ã¼ãã§ã¯åæè³æºæ°ãï¼ã¨ããã»ããã©($semaphore)ãçæãã
$dataããããç´åã«downã$dataã使ç¨ãçµãã£ããupãè¡ããã¨ã«ãããdownããupã¾ã§ã®æéãä»ã¹ã¬ããã$dataãå¤æ´ã§ããªã(downã§å¾
ã¡ç¶æ
ã«å
¥ã)ããã«ãã¦ãã¾ãã
ã½ã¼ã¹ã³ã¼ã
use strict; use threads; use threads::shared; use Thread::Semaphore; my $semaphore = Thread::Semaphore->new(1); my $data : shared; my @threads; print "Create threads\n"; foreach (1 .. 5){ my $thread = threads->new(\&my_thread, $_ , $semaphore); push(@threads, $thread); } print "Join threads \n"; foreach(@threads){ my ($return) = $_->join; print "$return closed\n"; } # ã¹ã¬ããã®å¦ç sub my_thread { my $i = shift; my $semaphore = shift; foreach(1 .. 20){ $semaphore->down; $data++; print "Thread $i b($data)\n"; sleep 1; print "Thread $i a($data)\n"; $semaphore->up; threads->yield(); } return ($i); }
å®è¡çµæ
Create threads Thread 1 b(1) Join threads Thread 1 a(1) Thread 2 b(2) Thread 2 a(2) Thread 5 b(3) Thread 5 a(3) Thread 1 b(4) Thread 1 a(4) Thread 2 b(5) Thread 2 a(5) Thread 5 b(6) Thread 5 a(6) Thread 1 b(7) Thread 1 a(7) Thread 2 b(8) Thread 2 a(8) Thread 5 b(9) Thread 5 a(9) (ç¥)
ã¹ã¬ãããå¤æ°ãåç
§ãã¦ããéãä»ã®ã¹ã¬ããã®å²ãè¾¼ã¿ãçºçãã¦ããªããã¨ãããããã¨æãã¾ãã
ãµã³ãã«ï¼ã®ä¾ã¨è¦æ¯ã¹ã¦ã¿ãã¨ãããã¨æãã¾ãã
ãµã³ãã«ï¼ï¼Thread::Queueã«ãããã¼ã¿ã®ããåã
æ¦è¦
Thread::Queueã使ãã¨ãã¹ã¬ããéã§ãã£ã¦ãå®å¿ãã¦ãã¼ã¿ã®ããåããå¯è½ã§ãã
ãã¥ã¼æ§é ã§ãã®ã§push(enqueueã¡ã½ãã)/pop(dequeue)ã¡ã½ããã使ç¨ãã¦æ ¼ç´ã»åãåºããè¡ãã¾ãã
ãã¥ã¼ã«è¦ç´ ãç¡ããªã£ãå ´åãdequeueã¡ã½ããã¯ãã¼ã¿åå¾å¾
ã¡ã«ãªããã¨ã«æ³¨æ(ã¨ã©ã¼çµäºãªã©ããªããã¤ã¾ãdequeueã¡ã½ãããå®äºããªãããã¼ã¿ãæ ¼ç´ãããã°è±åºãã¾ã)ã§ãã
ã§ãã®ã§ä¸è¨ã®ã½ã¼ã¹ã³ã¼ãã§ã¯ããã¨ãã¥ã¼ã«undefãå
¥ãã¦ã«ã¼ãè±åºç¨ã«ä½¿ã£ã¦ãã¾ãã
ãªããThread::Queueã§æ ¼ç´ã§ããã®ã¯ã¹ã«ã©ã¼å¤æ°ã®ã¿ã¨ã®ãã¨ã§ãã
ã½ã¼ã¹ã³ã¼ã
use strict; use threads; use Thread::Queue; # ãã¼ã¿ãæ ¼ç´ãã¾ã my $queue = new Thread::Queue; foreach (1 .. 100){ $queue->enqueue($_); } my @threads; print "Create threads\n"; foreach (1 .. 5){ my $thread = threads->new(\&my_thread, $_); push(@threads, $thread); $queue->enqueue(undef); } print "Join threads \n"; foreach(@threads){ my ($return) = $_->join; print "$return closed\n"; } # ã¹ã¬ããã®å¦ç # åã¹ã¬ããã¯ããã¿ã¤ãã³ã°ã§ãã¼ã¿ãqueueããæãåºãã¾ã sub my_thread { my $i = shift; while (my $q = $queue->dequeue){ print "Thread $i($q)\n"; threads->yield(); sleep 1*$i; # åã¹ã¬ããã®åä½æéããã©ãã©ã«ãªãããã«ãã(å®é¨ç¨) } return ($i); }
å®è¡çµæ
Create threads Thread 1(1) Thread 2(2) Thread 3(3) Thread 4(4) Join threads Thread 5(5) Thread 1(6) Thread 2(7) Thread 1(8) Thread 3(9) Thread 1(10) Thread 2(11) Thread 1(12) Thread 4(13) Thread 1(14) Thread 5(15) Thread 3(16) Thread 2(17) Thread 1(18) Thread 1(19) Thread 2(20) Thread 1(21) Thread 4(22) Thread 1(23) Thread 3(24) Thread 2(25) Thread 1(26) Thread 5(27) (ä¸ç¥) Thread 3(91) Thread 1(92) Thread 2(93) Thread 1(94) Thread 5(95) Thread 4(96) Thread 1(97) Thread 2(98) Thread 3(99) Thread 1(100) 1 closed 2 closed 3 closed 4 closed 5 closed
åã¹ã¬ããæ£å¸¸ã«queueã«æ ¼ç´ããããã¼ã¿ãåå¾ãã¦ãã¾ãã
Thread::Queueã使ç¨ããå ´åãï¼ã¤ã®ãã¼ã¿ãè¤æ°ã®ã¹ã¬ãããåå¾ãã¦ãã¾ããããªãã¨ã¯ããã¾ãã("50"ã®ãã¼ã¿ãã¹ã¬ããï¼ã¨ã¹ã¬ããï¼ãåå¾ãã¦ãã¾ããªã©)ã
åèURL
Life with IT
http://www.ornithopter.jp/archives/2006/03/perl_forkthread.html
Perlでマルチスレッド
perlでスレッド処理
threads - インタプリタスレッドの使用を可能にするPerl拡張
http://www.kawaz.jp/pukiwiki/?Perl%A4%C7%A5%DE%A5%EB%A5%C1%A5%B9%A5%EC%A5%C3%A5%C9
Thread::Semaphore - スレッドセーフなセマフォ
ãããã«
ãã®ããããæå¹ã«æ´»ç¨ããã°ä¸¦åãã¼ã¿åå¾ãå®ç¾ã§ãããããããªãã¨æã代表çãªã¹ã¬ããå¦çã調æ»ãã¦ã¿ã¾ããã
ã¾ã ã»ãã«ä¾¿å©ãããªã¡ã½ãããã¢ã¸ã¥ã¼ã«ãããã¿ããã§ãã使ãæ©ä¼ããªããããªäºæãããã®ã§èª¿ã¹ã¦ãªãã£ãããã¾ãã
ãªããWindowsã«ã¯ãããã¯ã¼ã¯ã®æ¥ç¶ä¸éæ°ããã£ãã¯ããªã®ã§100å並åã§ãã¼ã¿åå¾ã¿ãããªãã¨ã¯ã§ããªãã¯ãã