Auteur: Rik - 28 november 2009 - 11:25 - Gekeurd door: Rik - Hits: 2610 - Aantal punten: (0 stemmen)
Functie
Deze set objecten maakt het mogelijk om de voordelen die multithreading biedt te gebruiken in php.
Uitleg
Een uitgebreide uitleg over de achtergronden van deze manier van multithreaden heb ik in een tutorial verwerkt: multithreading strategie. Heel simpel gezegd worden de classes die van Thread afstammen als threads gebruikt en kunnen deze eenvoudig worden beheerd door gebruik te maken van de verschillende classes die van ThreadManager afstammen.
Gebruik
Het gebruik van de multithreader wordt duidelijk uit de voorbeelden die bij het script zijn gevoegd. In de constructor en bij het aanroepen van bepaalde functies kan een array met configuratie opties worden meegegeven: Overzicht van alle gebruikte configuratie opties.
De ‘file’ optie voor Process- en HttpThread en de ‘url’ optie voor CurlThread (afgeleide) classes zijn heel belangrijk. Standaard wordt aangenomen dat het script zichzelf moet openen als er niets wordt opgegeven. Deze zelfaanvragen moeten worden afgehandeld door de bijbehorende Thread::activate() functie aan te roepen. Zie hiervoor de voorbeelden.
Als er bij ProcessThreads geen ‘php’ optie wordt meegegeven, gaat het script er van uit dat deze al in het PATH is opgegeven. Als de ‘class’ niet wordt opgegeven wordt er vanuit gegaan dat de bij ‘function’ opgegeven functie niet in een class staat. Bij de int en float waarden betekent een null waarde steeds oneindig, dat wil zeggen dat deze optie niet als beperkende factor zal worden gebruikt.
Bij de ThreadManager mode optie moeten de constanten ThreadManager::RUN_START en ThreadManager::RUN_WAIT worden gebruikt. Een aantal functies maakt geen gebruik van een configuratie array, maar van een los argument of class constanten als argument. In de code staat steeds duidelijk aangegeven welke configuratie opties wanneer van toepassing zijn en hoe de functies moeten worden aangeroepen. Vaak hoeven maar enkele opties expliciet te worden meegegeven omdat standaardwaardes voor de meeste opties al in de code staan gedefinieerd.
Bij het aanroepen van een aantal ThreadManager functies kan een reference variabele worden meegegeven. Deze zal dan worden gevuld met relevante functie resultaten zoals het aantal gestarte en beëindigde Threads. Nuttige toepassingen hiervan staan in de voorbeelden.
Todo
De CurlThread en CurlThreadManager werken op zich goed, maar er zit soms een onverklaarbare vertraging in het starten en het wachten op resultaten. Ik ken de interne werking van curl niet exact, maar ik vermoed dat het daar iets mee te maken heeft. Dit is een belangrijk verbeterpunt. Andere verbeterpunten en mogelijke uitbereidingen staan in de code aangegeven.
Update 09/12/2009
Communicatiefout verholpen bij het versturen van grote hoeveelheden gegevens in de FunctionThreads. Apache verstuurde de gegevens in chunks als het boven een bepaalde grens was en van te voren niet precies wist hoeveel. Door de Content-Length header mee te geven gaat het nu goed. 12/12/2009
Voorbeeld 7 toegevoegd. 13/12/2009
Voorbeeld 8 toegevoegd.
Code:
Codevoorbeelden zijn bij het script gevoegd. De voorbeelden 1 t/m 6 zijn tests die vooral bedoeld zijn om de snelheden van de verschillende typen threads te testen. De resultaten die zijn verkregen door het testen op twee verschillende systemen staan in de tutorial.
In voorbeeld 7 wordt een opgegeven hoeveelheid willekeurige zoekopdrachten uitgevoerd op willekeurige servers van google. Door in plaats van 1, nu 10 threads te gebruiken wordt de tijd die dit kost ongeveer met een factor 5 verkort. Exacte getallen zijn natuurlijk afhankelijk van vele factoren.
In voorbeeld 8 wordt een grote rij getallen gesorteerd met het Quicksort algoritme. Hierbij blijkt multithreading niet de optimale oplossing te zijn. Hoewel verschillende rijen tegelijk kunnen worden gesorteerd, kost het starten van nieuwe threads kostbare tijd. Ook moeten grote hoeveelheden data worden uitgewisseld tussen het hoofdscript en de threads en dat kost nog meer tijd. Het geheugengebruik kan hierbij ook flink oplopen. Om dit gedeeltelijk op te lossen worden kleinere rijen getallen op de originele manier recursief gesorteerd binnen een bestaande thread. Toch levert dit nog geen tijdswinst op ten op zichte van het originele algoritme. Een aantal verbeterpunten worden duidelijk:
- de eerste soorteerronde moet binnen het hoofdscript plaatsvinden
- afgeronde threads moeten uit de threadmanager kunnen worden verwijderd om geheugen te besparen