ÓõíÝ÷åéá óôá threads êáé åéóáãùãÞ óôá Sockets
ÊÜôé ïé âïõôéÝò óôï ôóïõêáúôé, êÜôé ôá ôóßðïõñá, êÜôé ç ðïëõðëïêüôçôá ôïõ èÝìáôïò êáèõóôÝñçóáí ôçí ðïëõáíáìåíüìåíç óõíÝ÷åéá. ÁëëÜ öåõ, óõíå÷ßæù áêÜèåêôïò.
Ç ðëÞñçò åêìåôÜëëåõóç ôùí äõíáôïôÞôùí ôùí íÝùí Ç/Õ, óõíåðÜãåôáé ÷ñÞóç üëùí ôùí ðõñÞíùí êáé ôç äçìéïõñãßá åöáñìïãþí ðïõ åêôåëïýí ôá õðïëïãéóôéêÜ ôïõò êáèÞêïíôá ðáñÜëëçëá, ìïéñÜæïíôáò ôá óå ìéá ïìÜäá áðü äéáèÝóéìïõò åñãÜôåò íÞìáôá (working Threads). Ôï ëåéôïõñãéêü óýóôçìá, áíáèÝôåé ôçí åêôÝëåóç ôùí íçìÜôùí óôïõò õðÜñ÷ïíôåò ðõñÞíåò (cores).
Èá ó÷åäéÜóïõìå ìßá åöáñìïãÞ ðïõ èá ìðïñåß íá «êáôåâÜóåé» Ýíá ïëüêëçñï éóôüôïðï (www.monachos.gr) óå ôïðéêü äßóêï. Èá îåêéíÜ ìå ôçí ðñþôç óåëßäá (/forum/) êáé áöïý ôçí êáôåâÜóåé, èá øÜîåé ãéá ôéò õðÜñ÷ïõóåò áíáöïñÝò ôçò óå Üëëåò óåëßäåò (óôï ßäéï Þ Üëëï éóôüôïðï). Ç äéáäéêáóßá èá åßíáé áíáäñïìéêÞ. Ç áíÜãíùóç ìßáò óåëßäáò áðü Ýíá éóôüôïðï (âáóéêÞ ëåéôïõñãßá ôïõ ðåñéçãçôÞ) áðáéôåß ÷ñÞóç Sockets êáé ôïõ ðñùôïêüëëïõ HTTP 1.0/1.1
Sockets (õðïäï÷Þ)
Socket åßíáé ìéá õðïäï÷Þ ðïõ åðéôñÝðåé ôçí åðéêïéíùíßá áíÜìåóá óå 2 Ç/Õ (server & client) ãéá ôçí áíôáëëáãÞ äåäïìÝíùí ìÝóù ôçò äéêôõáêÞò õðïäïìÞò.
Óôü÷ïò åßíáé ç äçìéïõñãßá, áíÜìåóá óå äýï Üêñá, Ýíá éäåáôïý êõêëþìáôïò øçöéáêÞò åðéêïéíùíßáò.
Ôï Üêñï ôïõ ðåëÜôç åêêéíåß ôçí óýíäåóç, ÷ñçóéìïðïéþíôáò ìßá õðïäï÷Þ ðåëÜôç (client socket) ôçí äéåýèõíóç êáé ôçí èýñá ôïõ åîõðçñåôçôÞ. Ï åîõðçñåôçôÞò, ìÝóù ìßáò õðïäï÷Þò áíáìïíÞò (listening socket) õðïäÝ÷åôáé óõíäÝóåéò. ÊÜèå áßôçóç óýíäåóçò, äçìéïõñãåß ôï 2ç Üêñï, ìßá íÝá õðïäï÷Þ åîõðçñåôçôÞ (server socket) áðïêëåéóôéêÜ ãéá áõôÞ ôç óýíäåóç êáé óõíÞèùò Ýíá íÞìá ðïõ èá ÷åéñéóèåß ôçí åðéêïéíùíßá ôùí 2 Üêñùí.
http://www.inetdaemon.com/tutorials/...andshake.shtml
ÅöáñìïãÞ SiteGrab
Áí õðïèÝóïõìå üôé Ý÷ïõìå ìéá ïìÜäá áðü åñãÜôåò íÞìáôá êáé ìßá ëßóôá äéáöüñùí åñãáóéþí. ¸íáò åðéóôÜôçò äéáôçñåß ôçí ëßóôá åñãáóéþí åíçìåñùìÝíç, åëÝã÷åé ôçí äéáèåóéìüôçôá êÜèå åñãÜôç íÞìá êáé áíáèÝôåé åêêñåìåßò åñãáóßåò óå åëåýèåñïõò åñãÜôåò íÞìáôá Ýùò üôïõ üëïé ïé åñãÜôåò íÞìáôá åßíáé áðáó÷ïëçìÝíïé Þ Ý÷åé áíáèÝóåé üëåò ôéò åñãáóßåò ðñïò åêôÝëåóç. Ìüëéò ï åðéóôÜôçò ôåëåéþóåé ìå ôçí ëßóôá åñãáóéþí «êïéìÜôáé» (äåí êáôáíáëþíåé ðüñïõò ôïõ Ç/Õ) Ýùò üôïõ áíáôåèåß íÝá åñãáóßá. ºóùò, áðü êïéíùíéïëïãéêÞ Üðïøç, ìéá óýãêñéóç ìå ôï áíôßóôïé÷ï áíèñþðéíï ìïíôÝëï åñãáóßáò íá ìáò ïäçãïýóå óå åíäéáöÝñïíôá óõìðåñÜóìáôá.
Ç åöáñìïãÞ äçìéïõñãåß Ýíá object åñãáóßá êáé ôï áíáèÝôåé óôïí åðéóôÜôç ãéá íá ôï õëïðïéÞóåé.
ÊëÜóç Åñãáóßá
Ç êëÜóç åñãáóßá (TBasicWorkObject) ðåñéëáìâÜíåé üëá ôá áðáñáßôçôá äåäïìÝíá êáé ìßá ìÝèïäï åêôÝëåóçò ôçò.
Ïñßæåôáé óáí
Êþäéêáò:
TBasicWorkObject=class
public
procedure doWork; virtual; abstract;
end;
Ç ðñáãìáôéêÞ åñãáóßá TGrabUrl êëçñïíïìåß áðï ôçí TBasicWorkObject êáé ãíùñßæåé íá «êáôåâÜæåé» ìßá óåëßäá áðü Ýíá éóôüôïðï.
Êþäéêáò:
TGrabUrl=class(TBasicWorkObject)
private
FClientSocket: TClientSocket;
..
public
procedure doWork; override;
constructor Create(const aSite,aUrl:string;aDepth:integer); overload;
..
property Stream:TMemoryStream read FStream;
property Depth:integer read FDepth;
end;
Ç TGrabUrl.doWork êáôåâÜæåé ôçí óåëßäá êáé åíçìåñþíåé ôçí êýñéá öüñìá
Êþäéêáò:
postmessage(UIHandle,WORK_DONE,integer(self),0);
Åêåß ãßíåôáé ç åðåîåñãáóßá êáé ç áðïèÞêåõóç ôçò óåëßäáò.
ÊÜèå éóôüôïðïò Ý÷åé äåíäñéêÞ äïìÞ êáé êÜèå åðßðåäï ÷áñáêôçñßæåôáé áðï ôï âÜèïò ôïõ.
ÊëÜóç ÅðéóôÜôçò
Ç êëÜóç åðéóôÜôçò, äéáôçñåß ôçí ëßóôá åñãáóéþí ãéá êÜèå óåëßäá ðïõ ðñÝðåé íá êáôåâÜóåé êáé äçìéïõñãåß êáé åëÝã÷åé ôá íÞìáôá åñãÜôåò.
ÎõðíÜåé ðåñéïäéêÜ, êáé áí õðÜñ÷åé åñãáóßá êáé äéáèÝóéìï íÞìá åñãÜôçò ôçí ðñïãñáììáôßæåé ðñïò åêôÝëåóç.
Êþäéêáò:
TThreadsMngr=class(TThread)
private
FPeriod:integer;
FThreads,
FWorkQ :TObjectList;
...
public
constructor Create(WorkThreadClass:TWorkThreadClass;
DefThreadCount:integer=10);
...
procedure QueueWork(work:TBasicWorkObject);
end;
ÅñãÜôåò íÞìáôá
ÊÜèå åñãÜôçò íÞìá «êïéìÜôáé» êáé ðåñéìÝíåé 2 óçìáôïäüôåò (events) íá åíåñãïðïéçèïýí ãéá íá äïõëÝøåé Þ íá ôåñìáôßóåé. Åêôåëåß ôçí åñãáóßá ôïõ, êáëþíôáò ôçí ìÝèïäï TBasicWorkObject.doWork êáé ìüëéò ôåëåéþóåé îáíáêïéìÜôáé.
Êþäéêáò:
TWorkThread=class(TThread)
private
FWorkObj : TBasicWorkObject;
...
public
constructor Create(aId:integer;aHandle:THandle);
procedure Work(aWorkObj:TBasicWorkObject);
...
end;
procedure TWorkThread.Work(aWorkObj:TBasicWorkObject);
begin
FWorkObj:=aWorkObj;
FWorkEvent.SetEvent;
if Suspended then Resume; // FWorkEvent will signal imediatelly
end;
procedure TWorkThread.Execute;
begin
H[0] := FStopEvent.Handle;
H[1] := FWorkEvent.Handle;
while not Terminated do
case WaitForMultipleObjects(2, @H, False, INFINITE) of
WAIT_OBJECT_0 : Terminate; // StopEvent Signaled
WAIT_OBJECT_0 + 1 : begin // WorkEvent Signaled
try
FWorkObj.doWork;
except
end;
FWorkEvent.ResetEvent; // Lower WorkEvent
end;
end
end;
Óôï ðáñÜäåéãìá õëïðïßçóá ôçí áíÜãíùóç ôçò ðñþôçò óåëßäáò /forum/ áðü ôïí éóôüôïðï (www.monachos.gr ) êáé áíåýñåóç üëùí ôùí áíáöïñþí óå óåëßäåò (ð÷ http://www.monachos.gr/forum/topic.asp? TOPIC_ID=3931) 1ïõ åðéðÝäïõ ðïõ ðåñéÝ÷åé .
Ç áñ÷éêÞ óåëßäá áðïèçêåýåôáé óáí c:\temp\forum\default.htm
Ìðïñåßôå íá êáôåâÜóåôå ôçí åöáñìïãÞ êáé ôï source áðü ôï example02.rar
http://www.filefactory.com/file/1pjn.../Example02_rar
There always be one more bug.