Abitu arutelulõng php. Mitmelõimelisus PHP-s: pthreads. Skripti mitme koopia käitamine – üks koopia toimingu kohta

Mõnikord on vaja teha mitu toimingut korraga, näiteks kontrollida ühes andmebaasi tabelis muudatusi ja teha muudatusi teises. Veelgi enam, kui üks toimingutest (näiteks muudatuste kontrollimine) võtab kaua aega, on ilmne, et järjestikune täitmine ei taga ressursside tasakaalustamist.

Selliste probleemide lahendamiseks kasutab programmeerimine multithreadingut – iga operatsioon paigutatakse eraldi lõime, kus on selleks ette nähtud hulk ressursse ja töötab selle sees. Selle lähenemisviisi korral täidetakse kõik ülesanded eraldi ja iseseisvalt.

Kuigi PHP ei toeta multithreadingut, on selle emuleerimiseks mitu meetodit, millest tuleb juttu allpool.

1. Skripti mitme koopia käitamine – üks eksemplar toimingu kohta

//woman.php if (!isset($_GET["thread"])) ( system("wget"http://localhost/woman.php?thread=make_me_happy"); system("wget ​​​​http: //localhost/ woman.php?thread=make_me_rich"); ) elseif ($_GET["lõng"] == "make_me_happy") ( make_her_happy(); ) elseif ($_GET["thread"] == "make_me_rich") ) ( leia_teine_üks( ); )

Kui käivitame selle skripti ilma parameetriteta, käivitab see automaatselt kaks koopiat endast koos toimingu ID-dega ("thread=make_me_happy" ja "thread=make_me_rich"), mis käivitavad vajalikud funktsioonid.

Seega saavutame soovitud tulemuse - korraga tehakse kaks toimingut -, kuid see pole loomulikult mitmekeermeline, vaid lihtsalt kark ülesannete üheaegseks täitmiseks.

2. Jedi tee – PCNTL laienduse kasutamine

PCNTL on laiendus, mis võimaldab teil protsessidega täielikult töötada. Lisaks haldamisele toetab see sõnumite saatmist, oleku kontrollimist ja prioriteetide seadmist. Eelmine skript näeb PCNTL-i kasutades välja selline:

$pid = pcntl_fork(); if ($pid == 0) ( tee_tema_õnnelik(); ) elseif ($pid > 0) ( $pid2 = pcntl_fork(); if ($pid2 == 0) ( leia_teine_üks(); ) )

Tundub üsna segane, läheme rida-realt.

Esimesel real "kahveldame" praeguse protsessi (kahvel - protsessi kopeerimine kõigi muutujate väärtuste salvestamisest), jagades selle kaheks paralleelselt töötavaks protsessiks (praegune ja alam).

Et mõista, kus me alam- või vanemprotsessis hetkel oleme, tagastab funktsioon pcntl_fork lapse jaoks 0 ja vanema jaoks protsessi ID. Seetõttu vaatame teisel real $pid, kui see on null, siis oleme alamprotsessis - täidame funktsiooni, vastasel juhul oleme vanemas (rida 4), siis loome teise protsessi ja teostame ülesannet samal viisil.

Skripti täitmise protsess:

Seega loob skript veel 2 alamprotsessi, mis on selle koopiad ja sisaldavad samu muutujaid sarnaste väärtustega. Ja funktsiooni pcntl_fork tagastatud identifikaatori abil suunatakse meid, millises voos me parasjagu viibime, ja teeme vajalikud toimingud.

Minu hea sõbranna ema kaotas Peterburist Moskvasse suunduval lennul oma kohvri ja tal oli edasine lend soojadele randadele ja nüüd on ta juba kuurordis - ilma ujumistrikoo, sandaalideta ja ühe T-särgiga alates käsipagas. Vanast mälust andsin talle paar näpunäidet, mida teha ja kuhu joosta ning otsustasin täna kõik, mida antud teemal tean, siia kirja panna.

Selgitamaks, miks ma nii tark olen, tuletan meelde, et töötasin omal ajal mitme lennufirma maapealse teenindamise alal, sealhulgas tegelesin üksikute pagasi jälgimise küsimustega. Noh, pluss muidugi oma lennukogemus. Siiski, kuna Lahkusin lennuteenindusest mitu aastat tagasi, võib-olla võivad mõned nüansid muutuda - kui jah, siis võtan teemakohaseid kommentaare tänulikult vastu ja parandan postituses olevat infot.

Alustan sellest mida peate tegema, et teie pagas EI läheks kaotsi:
1. Rebi kohvrist maha kõik eelmiste reiside sildid ja kleebised, ka väikesed vöötkoodiga kleebised, mis sageli kleebitakse eraldi kohvri enda külge – need võivad pagasi skaneerimise ja sorteerimise automaatse süsteemi segamini ajada.
2. Riputage oma kohvrile (kott, kast, kimp - üldiselt kõik, mida te pagasisse registreerite) nimesilt nimesildiga: saate osta korduvkasutatava valiku ette või võtta pabersildi registreerimislauast - tavaliselt jagavad kõik enam-vähem korralikud lennufirmad neid ilma piiranguteta . Ja näiteks Emiratesil on üldiselt suurepärased plastist sildid vastupidava juhtme küljes, mis võib kesta väga kaua:

Vanad paranoid saavad hakkama nagu mina: mul on alati kohvri peal Samsonite komplekti kuuluv korduvkasutatav plastiksilt, kus on püsiv koduaadress, telefoninumber ja email ning kuhugi puhkusele lennates riputan lisaks veel paberlipiku, millele viitan. uues kohas viibimise kuupäevad ja kõik võimalikud kontaktid (hotelli nimi ja aadress, selle kohalik telefoninumber, kui see on olemas, ning loomulikult teie ees- ja perekonnanimi).
3. Kontrollige check-in lauas, et teie pagasile oleks kleebitud pagasilipik, mille check-in agent välja prindib – koos linna koodiga, kuhu lendate, ja lennu numbriga.
4. Kui teil on mitu jätkulendu, rääkige sellest check-in agentile ja täpsustage, kuhu soovite oma pagasit registreerida. Mõnel juhul tuleb pagas üles võtta ühes või teises marsruudi lennujaamas, olenemata teie soovist: see kehtib näiteks lennujaamade vahel (Orly ja Charles de Gaulle Pariisis, Domodedovo - Šeremetjevo) - " Vnukovo" Moskvas), eraldi terminalid (terminalid 1 ja 2 Frankfurdis) või esimeses saabumispunktis USA-s või Mehhikos - see on nende riikide tolli nõue: oletame, et lendate Moskva-Washington-Phoenixiga, Phoenixisse väljastatakse pagasilipik kõigi kolme segmendi kohta, kuid Washingtonis tuleb pagas füüsiliselt üles võtta, tollivormistuses läbi viia ja uuesti kontrollida. Kui registreerite ka vankri, mis teil lubati käiguteele viia, või looma, peate selle tõenäoliselt transiidipunktist järele võtma. Üldjuhul on ümberistumistega keerulise marsruudi puhul parem pagasi liikumise nüansid eelnevalt selgeks teha lennufirma kõnekeskuses või äärmisel juhul check-in’is.
5. Tee oma pagas nähtavaks: alati ei ole pagasi hilinemise põhjuseks teisaldajad või sorteerimissüsteemi rikked. Mõnikord võtab mõni teine ​​​​hajameelne reisija, kes on pärast pikka lendu väsinud, pagasilindilt samasuguse musta samsoniidi või mittemidagiütleva koti, nagu teil on. Seetõttu märkige oma pagas ära: riputage käepidemele hunnik heledaid paelu või väike pehme mänguasi, kleepige sellele suur kleebis või eelistage kohvri valimise etapis lihtsalt ebatavalist värvi.

Mida ei tohiks pagasisse registreerida?
Pidage meeles, et pagas lähevad kaduma kõikides lennufirmades ja kõikides lennujaamades. Statistika on muidugi kõigil erinev, kuid pagasi kaotada või hilineda võivad ka kõige usaldusväärsemad lennufirmad ja ka kõige väiksem lennujaam, kus üksainus laadija viib käru kohvritega otse check-in letist lennukisse. Seetõttu soovitan teil alati kaasa võtta käsipagas:
- olulised dokumendid, sealhulgas need, mida lennu ajal vaja ei lähe (nt viimasel Peterburi reisil oli mul vaja luba vahetada ja mul oli kaasas abielutunnistus ja kõikvõimalikud autokooli kaardid käsipagas)
- võtmed (koos teie aadressiga sildiga, see võib olla ohtlik)
- raha, ehted (ei kommenteeri)
- kallis habras varustus
- ravimid, mida võtate regulaarselt, lennuks vajalikus koguses ja väikese varuga juhuks, kui peate otsima analoogi mõnest välisriigist või linnast. Retseptiravimid, mida pagasi kaotsimineku korral on võimatu osta, võtke kaasa kogu reisiks vajalik kogus.
- midagi, mida võite saabumisel kiiresti vaja minna (nt telefoni laadija).
- midagi, millel on teie jaoks isiklikult sentimentaalne väärtus: mõnikord läheb pagas igaveseks kaduma ja kui isikliku päeviku kadumine murrab teie südame, on parem jätta see koju või võtta salongi kaasa

Õpetlik lugu: minu töö ajal Peterburi Lufthansas jooksis meie kontorisse üks abielupaar USAst, kes väänasid käsi - neil polnud kaasas pagasit, mis sisaldas lapsendamisprotsessi jaoks väga olulisi dokumente, kohus oli järgmine päev. Muidugi on pagasi kadumises süüdi lennufirma, aga keda see huvitab? Sellise olukorra vältimiseks piisas vaid tähtsate paberite käsipagasisse panemisest.

Niisiis, jõudsite kohale ja ei leidnud oma pagasit pagasilindilt. Mida teha?
1. Kui registreerisid sisse midagi muud kui tavakohvrid: suusad, tšello, täisseina plasmaekraan, vanker, elav marmorkoer, siis kontrolli, kas seal on eraldi äravõtupunkt nn. ülegabariidiline pagas ehk Bulky bagage – pagas, mis sarnaneb ülalkirjeldatule, laaditakse sageli eraldi kambrisse ja laaditakse ka käsitsi eraldi maha. Kui teie pagasit sealt ei leita
2. Minge Lost & Found või Lost & Found töölauale. Seal peate täitma spetsiaalse vormi, mis sisaldab üksikasjalikku teavet oma pagasi kohta: marsruut, välimus, lühike sisuloend, kontaktandmed alalises elukohas ja ajutine viibimine. Samuti näete pagasi jälgimise teenuses tõenäolisemalt järgmist pagasi tabelit:

Selle klassifikatsiooni järgi kodeeritakse teie kadunud pagas ja, et te aru saaksite, kodeeritakse need kaks kohvrit samal viisil:

Nii et lisage julgelt kirjeldusse rohkem üksikasju ja ärge jätke sisuosa vahele. Reeglina palutakse esmakordsel pagasi hilinemise akti (pagasi hilinemise aruanne) täitmisel märkida mitu sisu, mille järgi saab teie kotti tuvastada, kui välisküljel ja kotil puuduvad tunnusmärgid. tuleb avada (kui kott avatakse, panevad nad selle teate sisse). Halb näide: t-särk / raamat / niisked salvrätikud, hea näide: erkpunased bikiinid / Malevitši trükikataloog / kokkuklapitavad triikraud. Pärast avalduse täitmist annab pagasi jälgimise ametnik teile numbri vormingus XXXYY11111, kus XXX on saabumislennujaama kood, YY on saabumislennufirma kood + 5 numbrit taotluse seerianumbrist. : näiteks JFKLH12345, kui lendasite Lufthansaga New Yorgi Kennedy lennujaama. Pidage meeles või kirjutage see number üles – see on lihtsaim viis oma avalduse leidmiseks edasiste päringutega.
Samal numbril saate ise kontrollida otsitavate nimekirja olekut (Mingil põhjusel link lendab: kui see teie jaoks ei tööta, Google World Tracer Online ja sõna otseses mõttes teine ​​link - pealkirjaga Baggage Tracing veebisaidil worldtracer.aero - see on see, mida te vajate), sest kadunud ja leitud on sageli väga raske
3. Püüdke võtta ühendust oma lennufirma kontoriga saabumislennujaamas: mõnikord (rõhutan - VAHEL!), kui saabusite mitte koju, vaid ajutisse viibimiskohta (puhkus, ärireis), võib lennufirma pakkuda hügieenitarvete komplekt (Lufthansal on kaasas ülisuur T-särk, hambahari ja -pasta, juuksehari, šampooni ja dušigeeli väikesed pakendid, pesupulbri kott jne) või tehke väike sularahamakse väikeste kulude katteks. kohapeal (kohapealne sularahamakse).

Mis saab edasi?
Teie fail (nn AHL) saadetakse tsentraliseeritud pagasiotsingusüsteemi (World Tracer). Kõik väljavõtmata pagasiühikud langevad samasse otsingusüsteemi, olenemata sellest, kas need leiti ilma sildita pagasiruumi nurgast või jäid pagasilindile, iga nende esemete kohta luuakse ka fail formaadis XXXYY11111. ainult erinevast alamliigist - nn. aruanne või OHD. Kui AHL- ja OHD-failide andmed ühtivad (perekonnanimi, kohvri kirjeldus, marsruut jne), saavad mõlemad jaamad (kus nad teatasid pagasi kadumisest ja kust pagas leiti välja võtmata) ja seejärel tehnika küsimus: topeltkontroll ja õnnestumise korral pagasi suunamine soovitud linna. Muidugi tehakse ka palju käsitsitööd - sõnumite saatmine, sarnaste, kuid mitte samade kohvrite tagasilükkamine, pluss mitmetele telefonikõnedele vastamine - üldiselt ei hakka pagasi jälgimise ametnikel igav.
Ligikaudne statistika: enam kui 90% kadunud pagasist leitakse esimese 3 otsingupäevaga, 3% kaob jäädavalt.
Mida sa teha saad?
1. Kui pead saabumisel ostma midagi, mida hädasti vaja läheb (hambaharjast äriülikonnani), siis säilita kindlasti kviitungid hilisemaks hüvitiseks. Kallitest ilma vajaduseta ostudest tuleks aga loobuda, miks – selgitan hiljem.
2. Värskete lugude puhul koostage võimalikult üksikasjalik sisuloend, soovitavalt iga kauba värvi, kaubamärgi ja ligikaudse maksumusega, ideaaljuhul inglise keeles (sest vastasel juhul peab lennufirma töötaja selle loendi süsteemi tõlkima), võtke ühendust lennufirmaga ja saatke neile see nimekiri, lisatakse see pagasiotsingu rakendusse. Esimesed 5 päeva tegeleb saabumislennujaam pagasi otsimisega, seejärel suunatakse otsing vedaja lennufirmale (taotluse numbris märgitud lennufirma - mäletate JFKLH12345?) Ja 21 päeva pärast saate taotleda lõplik hüvitis.
3. Kui pärast 21 päeva möödumist pagasi kaotsimineku avalduse esitamise kuupäevast ei ole seda leitud, pöörduge hüvitisnõudega vedaja lennufirma poole. Kui ma ei eksi, siis aegumistähtaeg on 2 aastat, s.o. Hüvitist saate taotleda kahe aasta jooksul alates kahjunõude esitamise kuupäevast.

Hüvitise maksmine.
Hüvitise maksmiseks tuleb pöörduda oma lennufirma esindusse koos makseavalduse, lendu ja pagasi kadumise fakti kinnitavate dokumentidega (pardakaardid, pagasisildid, pagasinõude number, makse rekvisiidid). Kui ma ei eksi, siis Vene Föderatsioonis tuleb hüvitise otsus seaduslikult läbi vaadata 30 päeva jooksul. Samuti võidakse paluda hinnata sisu maksumust ja võimalusel esitada kohvri ja selles olevate asjade ostutšekid (saan aru, et see pole enamikul juhtudel realistlik, kuid see on osa protseduurist).
Varem tehti makseid äraantava pagasi kaalu alusel - umbes 20 dollarit kilogrammi kohta. Hiljem muudeti arveldussüsteemi ja lennufirmade vastutust piirati 1000 tingliku ühikuga (lennufirma sees arvestatakse tavaühiku väärtust), mis minu töötamise hetkel vastas ligikaudu 1300 eurole. Need. isegi kui tood tšeki Louis Vuittoni tuhandest Boliivia gekonahkast õmmeldud ja briljantidega topitud kohvri ostmiseks, siis üle 1300 euro ei saa.

Tundub, et PHP arendajad kasutavad paralleelsust harva. Sünkroonkoodi lihtsusest ma ei hakka rääkima, ühe lõimega programmeerimine on muidugi lihtsam ja selgem, kuid vahel võib paralleelsuse väike kasutamine tuua märgatava jõudluse tõusu.

Selles artiklis vaatleme, kuidas saab pthreadsi laiendit kasutades PHP-s saavutada mitme lõimega töötamist. Selleks on vaja installida PHP 7.x ZTS (Zend Thread Safety) versioon ja installitud pthreads v3 laiendus. (Kirjutamise ajal peavad PHP 7.1 kasutajad installima pthreads-hoidla põhiharust – vaadake kolmanda osapoole laiendust.)

Väike selgitus: pthreads v2 on PHP 5.x jaoks ja seda enam ei toetata, pthreads v3 on PHP 7.x jaoks ja seda arendatakse aktiivselt.

Pärast sellist kõrvalepõiget asume kohe asja kallale!

Ühekordsete ülesannete lahendamine

Mõnikord soovite ühekordseid ülesandeid töödelda mitme lõimega (näiteks mõne I/O-ga seotud ülesande täitmiseks). Sellistel juhtudel saate kasutada klassi Thread, et luua uus lõime ja käivitada töötlemine eraldi lõimel.

Näiteks:

$task = uus klass laiendab lõime ( privaatne $response; public function run() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+)~", $sisu, $vastused); $this->response = $sobib; ) ); $task->start() && $task->join(); var_dump($task->response); // string (6) "Google"

Siin on käitamismeetod meie töötlemine, mis viiakse läbi uue lõime sees. Kui kutsutakse Thread::start, luuakse uus lõim ja käivitatakse käivitamismeetod. Seejärel ühendame loodud lõime tagasi põhilõimega, kutsudes välja Thread::join , mis blokeerib seni, kuni loodud lõime on täitmise lõpetanud. See tagab, et ülesande täitmine lõpetatakse enne, kui proovime tulemust väljastada (mis salvestatakse kausta $task->response).

Klassi saastamine lõimeloogikaga seotud lisakohustustega (sealhulgas käitamismeetodi määratlemise vastutus) ei pruugi olla soovitav. Sellised klassid saame isoleerida, tuletades Threaded klassist. Seejärel saab neid käivitada teises lõimes:

Klassiülesanne laiendab lõime (public $response; public function someWork() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+) ~", $content, $matches); $ see->vastus = $vastab; ) ) $ülesanne = uus ülesanne; $thread = new class($task) extends Thread ( privaatne $task; public function __construct(Threaded $task) ( $this->task = $task; ) public function run() ( $this->task->someWork( ; ) ); $lõim->start() && $lõim->liitu(); var_dump($ülesanne->vastus);

Iga klass, mida tuleb käivitada eraldi lõimes, peab pärida keermestatud klassist. Seda seetõttu, et see pakub vajalikke võimalusi erinevate lõimede töötlemiseks, samuti kaudset turvalisust ja kasulikke liideseid (nt ressursside sünkroonimine).

Vaatame pthreadsi laiendi pakutavat klassi hierarhiat:

Keermestatud (rakestab läbitavat, kogutavat) Keermetöötaja volatile bassein

Oleme juba käsitlenud ja õppinud Threadi ja Threaded klasside põhitõdesid, nüüd vaatame ülejäänud kolme (Worker , Volatile ja Pool).

Lõime taaskasutus

Iga paralleelstamist vajava ülesande jaoks uue lõime käivitamine on üsna kulukas. Selle põhjuseks on asjaolu, et PHP-s mitmelõimelisuse saavutamiseks tuleb pthreadides rakendada "mitteühine" arhitektuur. Mis tähendab, et PHP-tõlgi praeguse eksemplari kogu täitmiskontekst (sh iga klass, liides, tunnus ja funktsioon) tuleb iga loodud lõime jaoks kopeerida. Kuna sellel on märgatav mõju jõudlusele, tuleks niiti võimaluse korral alati uuesti kasutada. Lõime saab uuesti kasutada kahel viisil: Worker s või Pool s.

Tööliste klassi kasutatakse ülesannete seeria sünkroonseks täitmiseks teises lõimes. Selleks luuakse Töötaja uus eksemplar (mis loob uue lõime) ja seejärel lükatakse ülesanded selle üksiku lõime virna (kasutades Worker::pinu).

Siin on väike näide:

Klassiülesanne laiendab keermestatud ( privaatne $väärtus; avalik funktsioon __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Task: ($this->value) \n"; ) ) $töötaja = uus Töötaja(); $töötaja->start(); for ($i = 0; $i pinu(new Task($i)); ) while ($töötaja->kogu()); $tööline->shutdown();

Ülaltoodud näites lükatakse 15 ülesannet uue $worker objekti virnasse meetodi Worker::stack kaudu ja seejärel töödeldakse neid lükkamise järjekorras. Meetodit Worker::collect, nagu ülal näidatud, kasutatakse ülesannete puhastamiseks niipea, kui need on täitmise lõpetanud. Sellega blokeerime while-tsükli sees põhilõime, kuni kõik virnas olevad ülesanded on lõpetatud ja kuni need on tühjendatud – enne kui kutsume Worker::shutdown . Töötaja ennetähtaegne lõpetamine (st seni, kuni ülesandeid on veel täita), blokeerib põhilõime endiselt seni, kuni kõik ülesanded on täitmise lõpule viinud, kuid ülesandeid ei koguta prügi (mis tähendab mälulekkeid).

Klass Worker pakub oma ülesannete virnaga seotud mitmeid muid meetodeid, sealhulgas Worker::unstack viimati sisestatud ülesande eemaldamiseks ja Worker::getStacked täitmisvirnas olevate ülesannete arvu hankimiseks. Töötaja virn sisaldab ainult ülesandeid, mis tuleb täita. Kui virnas olev ülesanne on täidetud, eemaldatakse see ja asetatakse prügikorjamiseks eraldi (sisemisse) virna (kasutades meetodit Worker::collect).

Teine viis lõime taaskasutamiseks paljude ülesannete jaoks on lõimekogumi kasutamine (Pool klassi kaudu). Lõimekogum kasutab ülesannete käivitamiseks töötajate rühma samaaegselt, milles samaaegsuse tegur (kogumi lõimede arv, millel see töötab) määratakse basseini loomisel.

Kohandagem ülaltoodud näidet töötajate kogumi kasutamiseks:

Klassiülesanne laiendab keermestatud ( privaatne $väärtus; avalik funktsioon __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Task: ($this->value) \n"; ) ) $pool = new Pool(4); for ($i = 0; $i submit(new Task($i)); ) while ($pool->collect()); $pool->shutdown();

Basseini ja töötaja kasutamisel on mõned märkimisväärsed erinevused. Esiteks ei pea basseini käsitsi käivitama, see hakkab ülesandeid täitma kohe, kui need on saadaval. Teiseks, meie saadaülesanded basseinile, mitte pane need virna peale. Samuti ei päri klass Pool Threadedilt ja seetõttu ei saa seda teistele lõimedele üle anda (erinevalt Workerist).

Hea tava kohaselt peaksid töötajad ja rühmad oma ülesanded alati puhastama kohe, kui nad on lõpetanud, ja seejärel need ise käsitsi lõpetama. Klassiga Thread loodud lõimed tuleb lisada ka emalõimele.

pthreads ja (mitte)muutus

Viimane klass, mida me puudutame, on Volatile , mis on pthreads v3 uus lisand. Muutumatuse mõistest on saanud p-lõimede oluline mõiste, kuna ilma selleta langeb jõudlus oluliselt. Seetõttu on vaikimisi keermestatud klasside atribuudid, mis on ise keermestatud objektid, nüüd muutumatud ja seetõttu ei saa neid pärast nende algset määramist üle kirjutada. Praegu eelistatakse selliste omaduste selgesõnalist muutlikkust ja seda saab siiski saavutada uue lenduva klassiga.

Vaatame näidet, mis demonstreerib uusi muutumatuse piiranguid:

Klassiülesanne laiendab Threaded // Threaded klassi ( avalik funktsioon __construct() ( $this->data = new Threaded(); // $this->data ei ole ülekirjutatav, kuna see on Threaded klassi atribuut Threaded ) ) $task = new class(new Task()) laiendab lõime ( // lõimega klass, kuna Thread laiendab lõime avalikku funktsiooni __construct($tm) ( $this->threadedMember = $tm; var_dump($this->threadedMember-> data); // objekt(Threaded)#3 (0) () $this->threadedMember = new StdClass(); // kehtetu, kuna atribuut on keermestatud klassi Threaded liige ) );

Lenduvate klasside keermestatud omadused on seevastu muudetavad:

Klassiülesanne laiendab volatile'i ( avalik funktsioon __construct() ( $this->data = new Threaded(); $this->data = new StdClass(); // kehtib, kuna oleme volatile klassis ) ) $task = new class(new Task()) laiendab lõime ( avalik funktsioon __construct($vm) ( $this->volatileMember = $vm; var_dump($this->volatileMember->data); // objekt(stdClass)#4 (0) () // endiselt kehtetu, kuna Volatile laiendab Threaded, seega on omadus endiselt Threaded klassi Threaded liige $this->volatileMember = new StdClass(); ) );

Näeme, et klass Volatile alistab Threaded vanemklassi poolt kehtestatud muutumatuse, et pakkuda võimalust muuta Threaded atribuute (nagu ka unset() ).

Mutatiivsuse ja volatile klassi teema käsitlemiseks on veel üks teema, mida arutada – massiivid. Pthreadides kantakse massiivid automaatselt lenduvatesse objektidesse, kui need määratakse Threaded klassi atribuudile. Seda seetõttu, et mitme PHP konteksti massiiviga manipuleerimine on lihtsalt ebaturvaline.

Mõne asja paremaks mõistmiseks vaatame uuesti näidet:

$massiivi = ; $task = new class($massiivi) laiendab Thread ( privaatne $andmed; public function __construct(massiivi $massiv) ( $this->data = $massiv; ) public function run() ( $this->data = 4; $ see->andmed = 5; print_r($see->andmed); ) ); $task->start() && $task->join(); /* Väljund: lenduv objekt ( => 1 => 2 => 3 => 4 => 5) */

Näeme, et lenduvaid objekte saab käsitleda nagu massiive, kuna need toetavad massiivi toiminguid, nagu (nagu ülal näidatud) alamhulga operaator (). Volatile klassid ei toeta aga põhilisi massiivi funktsioone, nagu array_pop ja array_shift . Selle asemel pakub Threaded klass meile sarnaseid toiminguid nagu sisseehitatud meetodid.

Demona:

$andmed = uus klass laieneb Volatile (avalik $a = 1; avalik $b = 2; avalik $c = 3; ); var_dump($andmed); var_dump($andmed->pop()); var_dump($andmed->shift()); var_dump($andmed); /* Väljund: objekt( [e-postiga kaitstud])#1 (3) ( ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) ) int(3) int(1) objekt ( [e-postiga kaitstud])#1 (1) (["b"]=> int(2) ) */

Muud toetatud toimingud hõlmavad Threaded::chunk ja Threaded::merge .

Sünkroonimine

Selle artikli viimases osas vaatleme pthreadide sünkroonimist. Sünkroonimine on meetod, mis võimaldab teil kontrollida juurdepääsu jagatud ressurssidele.

Näiteks rakendame lihtsat loendurit:

$counter = uus klass laiendab Thread ( public $i = 0; public function run() ( for ($i = 0; $i i; ) ) ); $counter->start(); for ($i = 0; $i i; ) $counter->join(); var_dump($loendur->i); // prindib arvu vahemikus 10 kuni 20

Ilma sünkroonimiseta ei ole väljund deterministlik. Mitu lõime kirjutavad samale muutujale ilma kontrollitud juurdepääsuta, mis tähendab, et värskendused lähevad kaotsi.

Parandame selle nii, et saaksime sünkroonimise lisamisega õige väljundi 20:

$loendur = uus klass laiendab Thread ( public $i = 0; public function run() ( $this->synchronized(function () ( for ($i = 0; $i i; ) )); ) ); $counter->start(); $loendur->sünkroniseeritud(funktsioon ($loendur) ( for ($i = 0; $i i; ) ), $loendur); $counter->join(); var_dump($loendur->i); // int(20)

Sünkroonitud koodiplokid saavad omavahel suhelda ka meetodite Threaded::wait ja Threaded::notify (või Threaded::notifyAll) abil.

Siin on alternatiivne juurdekasv kahes sünkroonitud tsüklis:

$counter = new class laiendab Thread ( public $cond = 1; public function run() ( $this->synchronized(function ()) ( for ($i = 0; $i notify();); if ($this->cond === 1) ( $see->kond = 2; $see->oota(); ) ) )); ) ); $counter->start(); $counter-> synchronized(function ($counter) ( if ($counter->cond !== 2) ( $counter->wait(); // oota, kuni teine ​​esimesena alustab ) for ($i = 10; $i teata(); if ($loendur->kond === 2) ( $counter->cond = 1; $counter->wait(); ) ) ), $counter); $counter->join(); /* Väljund: int(0) int(10) int(1) int(11) int(2) int(12) int(3) int(13) int(4) int(14) int(5) int( 15) int(6) int(16) int(7) int(17) int(8) int(18) int(9) int(19) */

Võite märgata lisatingimusi, mis on seatud Threaded::wait kõne ümber. Need tingimused on kriitilised, kuna võimaldavad sünkroonitud tagasihelistamist jätkata, kui see on saanud teate ja määratud tingimus on tõene. See on oluline, kuna teated võivad tulla mujalt kui Threaded::notify kutsumisel. Seega, kui meetodi Threaded::wait kutsed ei oleks tingimustega mähitud, käivitaksime valed äratuskõned, mis viib koodi ettearvamatu käitumiseni.

Järeldus

Vaatasime pthreads paketi viit klassi (Threaded , Thread , Worker , Volatile ja Pool) ja kuidas iga klassi kasutatakse. Vaatasime ka uut pthreadide muutumatuse kontseptsiooni, tegime lühikese ülevaate toetatud sünkroonimisfunktsioonidest. Kui need põhitõed on paigas, saame nüüd hakata uurima, kuidas p-lõime reaalses maailmas kasutada! See on meie järgmise postituse teema.

Kui olete huvitatud järgmise postituse tõlkest, andke mulle teada: kommenteerige suhtlusvõrgustikku. võrkudes, hääletage ja jagage postitust kolleegide ja sõpradega.

keermestatud arutelu

A keermestatud arutelu on elektrooniline arutelu (näiteks e-posti, e-posti loendi, teadetetahvli, uudistegrupi või Interneti-foorumi kaudu), milles tarkvara aitab kasutajal sõnumeid visuaalselt rühmitada. Sõnumid rühmitatakse tavaliselt visuaalselt teemade kaupa hierarhiasse. Sel viisil rühmitatud sõnumite kogumit nimetatakse a teemalõng või lihtsalt "lõng". Arutelufoorumil, e-posti kliendil või uudistekliendil on väidetavalt "lõimega teemad", kui see rühmitab samateemalised sõnumid sellisel viisil hõlpsaks lugemiseks. Lisaks võimaldavad lõimega arutelud tavaliselt vastata teatud postitustele teema lõimes. Selle tulemusena võib lõime teema sees olla arutelude hierarhia. Erinevat tüüpi tarkvara võib lubada selle hierarhia kuvamist teemade sees mida nimetatakse keermestatud režiimiks. (Alternatiiviks on lineaarne režiim, mis tavaliselt näitab kõiki postitusi kuupäeva järjekorras, olenemata sellest, kes võis kellele konkreetselt vastata.)

Eelised

Hierarhiliselt keermestatud vaadete eeliseks on see, et need võimaldavad lugejal kiiresti mõista vestluse üldist struktuuri: täpsemalt, kes kellele vastab. Sellisena on see kõige kasulikum olukordades, kus toimuvad pikemad vestlused või debatid, näiteks uudisterühmad: tõeliselt keeruka arutelu puhul muutub argumendi järgimine kiiresti võimatuks ilma mingisuguse hierarhilise lõimesüsteemita.

Teine eelis on kogukonna peenem hindamine hierarhiliselt keermestatud süsteemides. Kuna vastuseid tuleb anda konkreetsetele postitustele, tehakse neid ka konkreetsetele isikutele. Lõimitud vestlused keskenduvad seetõttu kirjutaja konkreetsetele vaadetele ja isiksusele, kellele vastatakse. Seda esineb harvemini foorumites, kus viimane kommentaar lisatakse lihtsalt üldkogumisse.

Puudused

Hierarhilise keermestamise puuduseks lamekeermestamise ees on suurem keerukuse tase ja seetõttu nõuab selline vaade selle kasutajatelt suuremat mugavust ja keerukust. Seetõttu pole üllatav, et selle kasutuselevõtt on olnud kõige suurem mõnes vanimas ja/või kõige keerukamas veebikogukonnas, nagu Usenet , CIX või Slashdot . Võrdluseks on veebivestlus- ja kommentaarisüsteemid nooremad ja laiemale publikule avatud ning sellisena on hierarhiline lõimestamine sellistel areenidel alles hiljuti tavaliseks muutumas.

Puuhierarhia pealesurumine kipub killustama ka diskussiooni teema sees: enam ei ole võimalik postitada sõnumit, mis vastaks mitmele varasemale postitusele või võtaks selle kokku. Selle asemel tuleb igale eelnevale postitusele eraldi vastata. Võib vaielda, kas see toob kaasa vastasseisvama arutelustiili foorumitel, kus kasutatakse hierarhilist lõime. Siiski, kuigi see võib olla tõsi, kui otsene lõimega vastus ei ole enam võimalik soovitud postituse vastuste hulga tõttu, kasutavad kasutajad nüüd sageli selle inimese tsitaate, kellele nad vastavad, et hoida vestlust õigel teel ja sujuv. sujuvalt. Seda soovitab enamik teadetetahvlite kogukondi juhuks, kui lõime on saavutanud oma muidu kõikehõlmava piiri.

avatud niit

Avatud lõim viitab ajaveebi postitusele, kus lugejad saavad kommenteerida ja arutada mis tahes valitud teemat. Tavaliselt on need kasulikumad populaarsetes suure liiklusega ajaveebides; neid kasutatakse sageli siis, kui ajaveebi autoril pole teemat, mille kohta postitada või kui postitamine on vaikne.

Avatud lõime kasutatakse ka blogide põhilehtedel olevate postituste monotoonsuse lõhkumiseks. Kommentaarid võivad koguneda sisule orienteeritud postitustele; Seetõttu kasutavad autorid avatud lõime, nii et lehe laadimisajad ei aeglustu.

Näited

* Yahoo! rühmad [ http://groups.yahoo.com/] , MSN Grupid [ http://groups.msn.com/] ja Slashdot [ http://www.slashdot.com/] kõik pakuvad veebipõhiseid foorumeid, mis sisaldavad keermestatud arutelusid.

Vaata ka

* Teaduslik taevakirjutamine
* Blogimise terminite loend

Viited

*Dartmouth. (2003). [ http://www.dartmouth.edu/~webteach/articles/discussion.html "Arutelu loomine võrgus" ]
*Wolsey, T. DeVere, [ http://www.readingonline.org/articles/art_index.asp?HREF=wolsey/index.html "Kirjandusarutelu küberruumis: noored noorukid, kes kasutavad raamatutest rääkimiseks keermestatud arutelugruppe] . "Reading Online", 7(4), jaanuar/veebruar 2004. Vaadatud 30. detsember 2007

Wikimedia sihtasutus. 2010 .

  • Leon Power
  • Barh Azoum

Vaadake teisi sõnastikke:

    interneti foorum- phpBB Internetifoorumi tarkvarapakett, üks populaarsemaid foorumipakette ... Wikipedia

    Virtuaalsete õpikeskkondade ajalugu 1990. aastad- Virtuaalsete õpikeskkondade ajaloos olid 1990. aastad kasvuaeg, eelkõige tänu taskukohase arvuti ja Interneti tulekule.1990ndad1990* Formal Systems Inc. Princeton, NJ, USA tutvustab DOS-põhist hindamist… … Wikipedia

    KOHV- Koostöö näost näkku hariduskeskkonna arendaja(d) LEAD konsortsium Stabiilne väljalase 5.0 / juuni 2010 Operatsioonisüsteem Platvormidevaheline … Wikipedia

    Vestluse lõimestamine- on paljude meiliklientide, teadetetahvlite, uudistegruppide või Interneti-foorumite kasutatav funktsioon, milles tarkvara aitab kasutajal sõnumeid visuaalselt rühmitada. Sõnumid rühmitatakse tavaliselt visuaalselt teemade kaupa hierarhiasse. Sõnumite komplekt, mis on rühmitatud… … Wikipedia

    Slashdot- Ekraanipilt Slashdot.org avalehe URL-ist slashdot.org loosungi uudised nohikutele. Asjad, mis loevad… Wikipedia

    MediaWiki- nimeruum suunab siia ümber. Abi saamiseks MediaWiki nimeruumi kohta Vikipeedias vt Abi:MediaWiki nimeruum. Üldist teavet Vikipeedia nimeruumide kohta leiate jaotisest Vikipeedia:nimeruum. Kõnelehe ja MediaWiki vestluslehe ümbersuunamine siia. For… …Wikipedia

    arvuti vahendatud suhtlus- Muude kasutuste kohta vt CMC (tähistus). Arvutiga vahendatud side (CMC) on defineeritud kui mis tahes suhtlustehing, mis toimub kahe või enama võrguga ühendatud arvuti kasutamise kaudu. Kuigi see termin on traditsiooniliselt viidanud neile… … Wikipediale

    Wiki tarkvara võrdlus- Järgmistes tabelites võrreldakse mitmete wiki tarkvarapakettide üldist ja tehnilist teavet. Sisukord 1 Üldteave 2 Sihtrühm 3 Funktsioonid 1 4 Funktsioonid 2 … Wikipedia

    Teaduslik taevakirjutamine- on kognitiivteadlase Stevan Harnadi loodud termin, mis kirjeldab mitme e-posti ja teemalõimega veebiarhiivi kombinatsiooni, nagu uudistegrupp, e-postiloend, hüperpost, netnews või Interneti-foorum, mis on lingitud ja kuupäeva järgi sorteeritav,… ... Wikipedia

    koostööl põhinev otsuste tegemise tarkvara- Koostööotsuste tegemise (CDM) tarkvara on tarkvararakendus või moodul, mis koordineerib õigeaegsete kollektiivsete otsuste tegemiseks vajalikke funktsioone ja funktsioone, võimaldades protsessis osaleda kõigil asjaomastel sidusrühmadel. … …Wikipedia

Proovisin hiljuti pthreade ja olin meeldivalt üllatunud – see on laiendus, mis lisab PHP-le võimaluse töötada mitme pärislõimega. Ei mingit emuleerimist, maagiat ega võltsinguid – kõik on tõeline.



Ma vaatan seda teemat. On palju ülesandeid, mis tuleb kiiresti täita. PHP-l on selle probleemi lahendamiseks muid tööriistu, neid siin ei mainita, artikkel räägib pthreadidest.



Mis on pthreads

See on kõik! Noh, peaaegu kõike. Tegelikult on midagi, mis võib uudishimuliku lugeja häirida. Ükski neist ei tööta standardse PHP-ga, mis on kompileeritud vaikevalikutega. Mitme lõimega töötamise nautimiseks peab teie PHP-s olema lubatud ZTS (Zend Thread Safety).

PHP seadistamine

Järgmiseks PHP koos ZTS-iga. Ignoreerige nii suurt täitmisaja erinevust võrreldes ilma ZTS-ita PHP-ga (37,65 vs 265,05 sekundit), ma ei üritanud PHP seadistust üldistada. Ilma ZTS-ita on mul näiteks XDebug lubatud.


Nagu näete, on 2 lõime kasutamisel programmi täitmiskiirus ligikaudu 1,5 korda suurem kui lineaarse koodi puhul. 4 niidi kasutamisel - 3 korda.


Võite märgata, et kuigi protsessor on 8-tuumaline, ei muutunud programmi täitmise aeg peaaegu 4 lõime kasutamisel. Tundub, et see on tingitud asjaolust, et minu protsessoril on 4 füüsilist tuuma.. Selguse huvides kujutasin diagrammi kujul plaati.


Kokkuvõte

PHP võimaldab pthreads laiendit kasutades üsna elegantset mitmelõimega töötlemist. See annab märgatava jõudluse tõuke.

Sildid: lisa sildid