| 
 
     
- UID
 - 2031431 
 - 威望
 - 27 点 
 - 金钱
 - 2 金币 
 - 点卡
 - 10 点 
 
  | 
1#
 
发表于 2003-12-10 02:14
 |  只看该作者
 
 
 
 [转帖]為什麼要用IO::Poll?
作者:apile  
 
因為使用IO::Select時候,因為其儲存handle是存在。。。。。。  
以下資料為本人閱讀Nework Programming With Perl的記要..  
有興趣的自己研究研究...  
------------------------------------------------------------------------------ 
date: 2003/06/22  
 
IO: oll的使用說明:  
在5.6版本的時候開始發展,功能完整的版本為0.04版。所以要注意的是IO: oll版本一定要是0.04以上。  
 
為什麼要用IO: oll?因為使用IO::Select時候,因為其儲存handle是存在bit vector裡面,因此必須針對所有監控中的Handle一個一個去Scan,找出可以Read/Write的handle。因此在效能的Issue上,當遇到大量的handle需要監控時,就會產生效能上的降低。而IO::Poll的機制則不是這麼回事,他同樣可以監控大量的HANDLE,但是利用array儲存這些handle,因為array的儲存機制,並不同於bit vector,並不需要一個一個去Scan這些handle,所以在效能上比較好。  
 
IO::Poll只需要一個Object就可以處理所有的handle,透過bitmask將Event傳給被監控的Handle,一旦符合需求,可以從handle中取出。  
 
IO::Poll接受的Event(mask):  
可讀的  
POLLIN:一般與有Priority的資料  
POLLRDNORM:一般的資料  
POLLRDBAND:有Priority的資料  
POLLPRI:特別高的Priority  
可寫的  
POLLOUT:一般與有Priority的資料  
POLLWRNORM:一般的資料  
POLLWRBAND:有Priority的資料  
有錯誤的  
POLLHUP:HangUp發生  
POLLNVAL:handle不合法  
POLLERR:有Error發生,如果是Socket可用sockopt(SO_ERROR)取得Error內容  
 
IO::Poll的method  
1.$poll=IO::Poll->new():產生IP::Poll的Object  
2.$mask=$poll->mask($handle,[$mask])  
取得或設定目前handle的 event bitsmask,如果mask沒給,則目前的設定值回傳。如果有給mask則將該mask設定給該handle。如果mask為0,則從list將該handle移除。所有的handle預設都會監控(POLLNVAL、POLLERR、POLLHUP)。  
3.$poll->remove($handle)  
同$poll->mask($handle,0);  
4.$events=$poll->poll([$timeout])  
等候有任何一個監控中的handle可以被讀取或寫入。回傳Event Type。  
5.@handles=$poll->handles([$mask])  
取出符合mask的handles。  
6.$mask = $poll->events($handle)  
取得$handles的所有mask。- #!/usr/bin/perl 
 - # file : test.pl 
 - # usage: test.pl [host] [port] 
 - # 利用IO::Poll達到多工的技術 
 - #--加載module 
 - use strict; 
 - use IO::Socket; 
 - #--引用後面的constant 
 - use IO::Poll qw( POLLIN POLLOUT POLLERR POLLHUP); 
 - use Errno qw(EWOULDBLOCK); 
 - #--設定Buffer的最大值 
 - use constant MAXBUF =>8192; 
 - #--忽略掉HANG HUP的Signal 
 - $SIG{PIPE} = 'IGNORE'; 
 - #--設定全域變數,兩個buffer兩個flag 
 - my ( $to_stdout,$to_socket,$stdin_done,$sock_done); 
 - #--取得 host and port 
 - my $host = shift or die "Usage: test.pl host [port]\n"; 
 - my $port = shift || 'echo'; 
 - #--建立Socket 
 - my $socket = IO::Socket::INET->new("$host:$port") or die $@; 
 - my $poll = IO::Poll->new() or die "Can't create IO::Poll object"; 
 - #--一開始先將STDIN與$socket放入list中,並將其mask設定為POLLIN準備讀取。 
 - $poll->mask(\*STDIN => POLLIN); 
 - $poll->mask($socket => POLLIN); 
 - #--設定標準輸出與$socket為noblocking mode 
 - $socket->blocking(0); # turn off blockingon the socket 
 - STDOUT->blocking(0);  # and on STDOUT 
 - #--main loop,$poll->handles會回傳所有正在監控中的handle 
 - while($poll->handles){ 
 - #--等候直到有事件符合 
 -   $poll->poll; 
 -   # 處理可讀取的事件 
 -   for my $handle ($poll->handles(POLLIN|POLLHUP|POLLERR)){ 
 -     if($handle eq \*STDIN){ 
 -   #?#93;資料讀取表示STDIN已經終止,否則將資料放入to_socket buffer中 
 -     $stdin_done++ unless sysread(STDIN,$to_socket,2048,length $to_socket); 
 -     } 
 -     elsif($handle eq $socket){ 
 -   # ?#93;資料讀取表示Socket已經讀取完畢,否則將資料附入to_stdout buffer中 
 -    $sock_done++ unless sysread($socket,$to_stdout,2048,length $to_stdout); 
 -     } 
 -   } 
 -   # 處理可寫入的事件 
 -   for my $handle ($poll->handles(POLLOUT|POLLERR)){ 
 -      if($handle eq \*STDOUT){ 
 -        my $bytes = syswrite(STDOUT,$to_stdout); 
 -      # 假若不是EWOULDBLOCK,表示真的有Error發生,所以才無法寫入 
 -        unless ($bytes){ 
 -           next if $! == EWOULDBLOCK; 
 -           die "write to stdout failed: $!"; 
 -        } 
 -      # 如果發生Partial Write將已經寫出的先清掉。 
 -        substr($to_stdout,0,$bytes) = ''; 
 -      } 
 -      elsif($handle eq $socket){ 
 -        my $bytes = syswrite($socket,$to_socket); 
 -        unless ($bytes){ 
 -           next if $! == EWOULDBLOCK; 
 -           die "write to socket failed: $!"; 
 -        } 
 -        substr($to_socket,0,$bytes) = ''; 
 -      } 
 -   } 
 - } continue { 
 -   # 每次While loop執行時都會執行到這兒 
 -   # 先設定三個bitmask為0,表示將從list中將該handle移除 
 -   my ($outmask,$inmask,$sockmask) = (0,0,0); 
 -   # 設定stdout的mask,假如有資料要寫出去,則將其mask設為可寫(POLLOUT) 
 -   $outmask = POLLOUT if length $to_stdout > 0; 
 -   # 當 to_socket的資料長度比MAXBUF大、或socket已經完結 
 -   # 或stdin已經完結,都不成立時,則設定STDIN可讀取。 
 -   $inmask = POLLIN unless length $to_socket >= MAXBUF 
 -                       or ($sock_done || $stdin_done); 
 -   # 假如有資料要寫出去,設定$socket為POLLOUT(待寫) 
 -   $sockmask = POLLOUT if length $to_socket>0; 
 -   # 同STDIN定義,但是|=表示附加上去,因為Socket可以同時讀寫 
 -   $sockmask |= POLLIN unless length $to_stdout>=MAXBUF or $sock_done; 
 -   # 設定STDIN、STDOUT、Socket三個handle的bitmask 
 -   $poll->mask(\*STDIN => $inmask); 
 -   $poll->mask(\*STDOUT=> $outmask); 
 -   $poll->mask($socket => $sockmask); 
 -   # 如果$stdin_done為真且已經?#93;有資料送出至$socket了,則將$socket 關?#93; 
 -   $socket->shutdown(1) if $stdin_done and !length($to_socket); 
 - } 
 
  复制代码 |   
 
 
 
哈哈哈!!!!你的IP是不是 ?我都知道了!!! | 
 
 
 
 |