PHP-version valinta Windowsille. Monisäikeinen laskenta PHP:ssä: pthreads Mikä on pthreads

Kokeilin äskettäin psäikeitä ja olin iloisesti yllättynyt - se on laajennus, joka lisää mahdollisuuden työskennellä useiden todellisten säikeiden kanssa PHP:ssä. Ei emulointia, ei taikuutta, ei väärennöksiä - kaikki on totta.



Harkitsen tällaista tehtävää. Siellä on joukko tehtäviä, jotka on suoritettava nopeasti. PHP:llä on muita työkaluja tämän ongelman ratkaisemiseen, niitä ei mainita tässä, artikkeli käsittelee psäikeitä.



Mitä ovat pthreadit

Siinä kaikki! No melkein kaikki. Itse asiassa on jotain, joka voi järkyttää utelias lukija. Mikään näistä ei toimi tavallisella PHP:llä, joka on käännetty oletusasetuksilla. Jotta voit nauttia monisäikeestä, sinun on oltava ZTS (Zend Thread Safety) käytössä PHP:ssäsi.

PHP-asetukset

Seuraavaksi PHP ja ZTS. Älä välitä suuresta suoritusajan erosta verrattuna PHP:hen ilman ZTS:tä (37,65 vs 265,05 sekuntia), en yrittänyt yleistää PHP-asetuksia. Jos kyseessä on ilman ZTS:ää, minulla on esimerkiksi XDebug käytössä.


Kuten näet, käytettäessä kahta säiettä ohjelman suoritusnopeus on noin 1,5 kertaa suurempi kuin lineaarisen koodin tapauksessa. Käytettäessä 4 lankaa - 3 kertaa.


Huomaa, että vaikka prosessori on 8-ytiminen, ohjelman suoritusaika pysyi lähes ennallaan, jos käytettiin enemmän kuin 4 säiettä. Näyttää siltä, ​​​​että tämä johtuu siitä, että prosessorissani on 4 fyysistä ydintä. Selvyyden vuoksi olen kuvannut levyn kaavion muodossa.


Yhteenveto

PHP:ssä on mahdollista työskennellä varsin tyylikkäästi monisäikeistyksen kanssa käyttämällä pthreads-laajennusta. Tämä lisää huomattavasti tuottavuutta.

Tunnisteet: Lisää tunnisteita

Lankakeskustelu

A kierteistä keskustelua on sähköinen keskustelu (kuten sähköpostin, sähköpostilistan, ilmoitustaulun, uutisryhmän tai Internet-foorumin kautta), jossa ohjelmisto auttaa käyttäjää ryhmittelemällä viestejä visuaalisesti. Viestit ryhmitellään yleensä visuaalisesti aihekohtaiseen hierarkiaan. Tällä tavalla ryhmiteltyä viestijoukkoa kutsutaan a aiheen lanka tai yksinkertaisesti "lankaa". Keskustelufoorumilla, sähköpostiohjelmalla tai uutisasiakkaalla sanotaan olevan "ketjutettuja aiheita", jos se ryhmittelee samaa aihetta koskevat viestit yhteen, jotta se on helppo lukea tällä tavalla. Lisäksi ketjutettujen keskustelujen avulla käyttäjät voivat yleensä vastata tiettyyn viestiin aiheen säikeessä. Tämän seurauksena keskustelujen hierarkia voi olla ketjun aiheen sisällä. Erityyppiset ohjelmistot voivat mahdollistaa tämän hierarkian näyttämisen missä kutsutaan säikeitetyksi tilaksi. (Vaihtoehtona on lineaarinen tila, joka näyttää tyypillisesti kaikki viestit päivämääräjärjestyksessä riippumatta siitä, kuka on vastannut kenelle.)

Edut

Hierarkkisesti ketjutettujen näkemysten etuna on, että niiden avulla lukija ymmärtää nopeasti keskustelun kokonaisrakenteen: erityisesti kuka vastaa kenelle. Sellaisenaan se on hyödyllisin tilanteissa, joissa on laajennettuja keskusteluja tai keskusteluja, kuten uutisryhmiä: todellakin monimutkaisissa keskusteluissa on nopeasti mahdotonta seurata argumenttia ilman jonkinlaista hierarkkista ketjutusjärjestelmää.

Toinen etu on yhteisön hienovaraisempi arvostus hierarkkisesti säikeitetyissä järjestelmissä. Koska vastaukset on annettava tiettyihin viesteihin, ne tehdään myös tietyille henkilöille. Lankakeskustelut keskittyvät siksi kirjoittajan erityisiin näkemyksiin ja persoonallisuuksiin sen yksilön, johon vastataan. Tätä tapahtuu vähemmän foorumeilla, joissa viimeisin kommentti lisätään vain yleiseen pooliin.

Haitat

Hierarkkisen kierteityksen haittapuoli litteään kierteitykseen verrattuna on lisääntynyt monimutkaisuus, ja siksi tällainen näkymä vaatii käyttäjiltä lisääntynyttä mukavuutta ja hienostuneisuutta. Siksi ei ole yllättävää, että sen käyttöönotto on ollut voimakkainta joissakin vanhimmissa ja/tai kehittyneimmissä verkkoyhteisöissä, kuten Usenet, CIX tai Slashdot. Verkkokeskustelu- ja kommenttijärjestelmät ovat verraten nuorempia ja avoimia laajemmalle yleisölle, ja sellaisena hierarkkinen ketjuttaminen on vasta äskettäin yleistynyt tällaisilla areenoilla.

Puuhierarkian asettamisella on myös tapana pirstalla keskustelua aiheen sisällä: ei enää ole mahdollista lähettää viestiä, joka vastaa tai tiivistää useisiin eri aikaisempiin viesteihin. Sen sijaan jokaiseen aikaisempaan viestiin on vastattava erikseen. Voidaan väittää, että tämä johtaa vastakkaisempaan keskustelutyyliin foorumeilla, jotka käyttävät hierarkkista lankaa. Vaikka se olisikin totta, jos suora ketjutettu vastaus ei ole enää mahdollista haluttuun viestiin annettujen vastausten suuren määrän vuoksi, käyttäjät käyttävät nyt usein vastaajansa lainauksia pitääkseen keskustelun raiteina ja sujuvana. sujuvasti Useimmat ilmoitustauluyhteisöt suosittelevat tätä siinä tapauksessa, että ketjuttaminen on saavuttanut muuten kattavan rajansa.

Avaa lanka

Avoin ketju viittaa blogikirjoitukseen, jossa lukijat voivat kommentoida ja keskustella mistä tahansa valitsemastaan ​​aiheesta. Ne ovat yleensä hyödyllisempiä suosituissa blogeissa, joissa on paljon liikennettä; niitä käytetään usein, kun blogin kirjoittajalla ei ole aihetta julkaista tai kun lähettäminen on tyyntä.

Avoimia säikeitä käytetään myös rikkomaan blogien pääsivuilla olevien viestien yksitoikkoisuutta. Kommentteja voi kertyä sisältösuuntautuneisiin viesteihin; siksi kirjoittajat käyttävät avoimia säikeitä, jotta sivujen latausajat eivät hidastu.

Esimerkkejä

*Yahoo! Ryhmät [ http://groups.yahoo.com/], MSN-ryhmät [ http://groups.msn.com/] ja Slashdot [ http://www.slashdot.com/] kaikki tarjoavat verkkopohjaisia ​​keskustelupalstoja, joissa on keskusteluketjuja.

Katso myös

* Tieteellinen Skywriting
* Luettelo bloggaamisen termeistä

Viitteet

*Dartmouth. (2003). [ http://www.dartmouth.edu/~webteach/articles/discussion.html "Keskustelu verkossa" ]
*Wolsey, T. DeVere, [ http://www.readingonline.org/articles/art_index.asp?HREF=wolsey/index.html "Kirjallisuuskeskustelu kyberavaruudessa: Nuoret nuoret keskustelevat kirjoista keskusteluryhmissä] . "Reading Online", 7(4), tammi/helmikuu 2004. Haettu 30. joulukuuta 2007

Wikimedia Foundation. 2010.

  • Leon Powe
  • Barh Azoum

Katso muita sanakirjoja:

    Internet-foorumi- phpBB Internet Forum -ohjelmistopaketti, yksi suosituimmista foorumipaketeista… Wikipedia

    Virtuaalisten oppimisympäristöjen historia 1990-luku- Virtuaalisten oppimisympäristöjen historiassa 1990-luku oli kasvun aikaa, mikä johtui pääasiassa edullisen tietokoneen ja Internetin tulosta.1990s1990* Formal Systems Inc. Princeton, NJ, USA esittelee DOS-pohjaisen arvioinnin... ... Wikipedia

    KAHVI- Collaborative Face to Face Educational Environment Kehittäjä(t) LEAD-konsortio Vakaa julkaisu 5.0 / kesäkuu 2010 Käyttöjärjestelmä Cross platform … Wikipedia

    Keskustelun ketjuttaminen- on monien sähköpostiohjelmien, ilmoitustaulujen, uutisryhmien tai Internet-foorumien käyttämä ominaisuus, jossa ohjelmisto auttaa käyttäjää ryhmittelemään viestejä visuaalisesti. Viestit ryhmitellään yleensä visuaalisesti aihekohtaiseen hierarkiaan. Joukko viestejä ryhmiteltynä... ... Wikipediaan

    Slashdot- Kuvakaappaus Slashdot.org-pääsivun URL-osoitteesta slashdot.org-iskulause Uutiset nörteille. Asiat, joilla on merkitystä...Wikipedia

    MediaWiki- nimiavaruuden uudelleenohjaukset tänne. Ohjeita MediaWiki-nimiavaruudesta Wikipediassa on kohdassa Ohje:MediaWiki-nimiavaruus. Yleistä tietoa Wikipedian nimiavaruuksista löytyy kohdasta Wikipedia:Nimiavaruus. Keskustelusivun ja MediaWikin keskustelusivun uudelleenohjaus tänne. ... ... Wikipedialle

    Tietokonevälitteinen viestintä- Muita käyttötarkoituksia varten katso CMC (täsmennys). Tietokonevälitteisellä viestinnällä (CMC) tarkoitetaan mitä tahansa viestintätapahtumaa, joka tapahtuu kahden tai useamman verkkoon liitetyn tietokoneen käytön kautta. Vaikka termillä on perinteisesti viitattu niihin… … Wikipediaan

    Wiki-ohjelmiston vertailu- Seuraavissa taulukoissa verrataan yleisiä ja teknisiä tietoja useista wiki-ohjelmistopaketeista. Sisältö 1 Yleistä 2 Kohdeyleisö 3 Ominaisuudet 1 4 Ominaisuudet 2 … Wikipedia

    Tieteellinen Skywriting- on kognitiotieteilijän Stevan Harnadin keksimä termi, joka kuvaa useiden sähköpostien ja aiheeseen ketjutetun verkkoarkiston, kuten uutisryhmän, sähköpostilistan, hypermailin, netnews- tai Internet-foorumin yhdistelmää, linkitettynä ja lajiteltavissa päivämäärän mukaan,… … Wikipedia

    Yhteistyöllinen päätöksentekoohjelmisto- Collaborative Decision Making (CDM) -ohjelmisto on ohjelmistosovellus tai moduuli, joka koordinoi toimintoja ja ominaisuuksia, joita tarvitaan oikea-aikaisten kollektiivisten päätösten tekemiseen, jolloin kaikki asiaankuuluvat sidosryhmät voivat osallistua prosessiin. ... ... Wikipedia

Huomio! Tämä artikkeli on toivottoman vanhentunut tai kirjoittaja arvioi, ettei sillä ole informaatiohyötyä.

Avoimen lähdekoodin kauneus on sen avoimuus :)) Eli. jos sinulla on älyä/aikaa/halua, voit selvittää tarkalleen kuinka ohjelma toimii. Tällaisen koodin haittapuoli on vaikeus saada tarvittavat käännetyt paketit. Esimerkiksi PHP voidaan ladata lähteeksi Nix-järjestelmille myöhemmän käännöksen/kokoonpanon kanssa. Kaikki on jo koottu Windowsille, mutta valmiita binaaripaketteja on paljon! Vaihtoehdot " lankaturvallinen/kierteetön", VC6/VC9 ja itse PHP:n eri versioita. Artikkeli luotiin selventämään tilannetta. Se perustuu eri lähteisiin, osittain englanninkielisiin käännöksiin. Kaikki sen vuoksi, että ensi kerralla minun ei tarvitse keksiä sitä uudestaan ​​- "mitä järkeä!?"

Tarvittu PHP versio riippuu sen web-palvelimen versiosta, jolla sitä käytetään. Esimerkiksi Apache 1.3.x toimii PHP version 3.0.x kanssa, Apache 2.x toimii PHP version 4.0 ja uudemman kanssa. Mutta tämä ei ole sellainen ongelma, keskity uudempiin vakaaihin julkaisuihin ja siihen, mitä isännöitsijällä on.

Millaisia ​​jälkikirjoituksia VC6, VC9, VC11? PHP-lähteet Windowsille on käännetty Visual Studiossa. VC9 saadaan, kun se on käännetty versiossa VS 2008, VC11 - Visual Studio 2012. Näin ollen, jotta tämä koko asia toimisi, tietokoneellesi on asennettava kirjastot Visual C++ -uudelleenjaettava Visual Studiolle vastaava vuosi. Vähän selvennystä tähän asiaan.

Lisäksi, jos verkkopalvelimesi on vanha Apache osoitteesta apache.org, sinun on ladattava PHP:n VC6-versio, jonka kääntämiseen käytettiin If PHP:tä IIS:lle tai uudemman Apachen kanssa , sitten voit kerätä jotain nykyaikaisempaa ;)

Minulle suurin este valinnassa on isäntä. Nyt on vakaa versio PHP 5.5.4:stä, mutta hänellä on edelleen 5.2.17!

Nyt mielenkiintoinen osa: " lanka turvallinen tai ei lanka turvallinen?"
Artikkelin ilmainen käännös (Dominic Ryan, 27.09.2007)

En ole koskaan nähnyt näin rikkinäistä englantia:((Halusin kääntää artikkelin nopeasti, mutta minulla on vaikeuksia ymmärtää, mitä kirjoittaja kirjoitti. Jatkuvat siirtymät "mikä-on-se" ja monimutkaisten lauseiden välillä tekevät Moskovasta yleensä erottuvan. Käännös kielelle Venäjän kieli on yhtä monimutkaista, koska minulla ei ole tarpeeksi tietoa ja mielikuvitusta kuinka kutsua oikein venäjäksi jotain, joka on yleensä kirjoitettu vain englanniksi.%) Esimerkiksi, en ole koskaan nähnyt teknistä käsitettä "moniprosessiarkkitehtuuri" venäjäksi, mutta helmeni on "virtaus-turvaton" on yleensä maalaisjärjen kysymys. Yleensä kerron mitä tapahtui.

Ero välillä lanka turvallinen Ja lankaturvallinen PHP binaariset paketit

Siitä lähtien, kun PHP ilmestyi ensimmäisen kerran Windowsissa 20. lokakuuta 2000 PHP 3.0.17:n kanssa, sen binaaripaketit on aina rakennettu kierreturvallinen (TS). Syy on seuraava: Windows käyttää monisäikeistä arkkitehtuuria ja Nix-järjestelmät tukevat moniprosessiarkkitehtuuria. Jos PHP on käännetty moniprosessiiseksi CGI-sovellukseksi monisäikeisen sijaan, sen käyttö CGI-moduulina Windowsissa IIS-palvelimella johtaa vakaviin hidastumiseen ja suorittimen käyttöön. Toisaalta voit yhdistää PHP:n IIS:ään ISAPI-moduulina ( vaaditaan monisäikeinen rakenne- noin kääntäjä). Sitten syntyy toinen ongelma: jotkut suositut PHP-laajennukset on suunniteltu Unix/Linuxia ajatellen, ts. moniprosessiarkkitehtuurilla, mikä johtaa IIS:ään ISAPI-moduulina yhdistetyn PHP:n kaatumiseen. Että. CGI-luonti on PHP:n vakain ympäristö IIS:ssä, ja sen suurin haittapuoli on, että se on hirvittävän hidas. Meidän on ladattava ja purettava koko PHP-ympäristö muistista aina, kun on pyyntö.

Tuolloin oli useita vaihtoehtoja parantaa PHP:n suorituskykyä IIS:ssä. Ensimmäinen on käyttää opkoodin välimuistia eAcceleratorin kaltaisten ohjelmien kanssa, jotka tallentavat PHP-komentosarjat osittain käännetyssä tilassa levylle ja/tai muistiin. Tämä lähestymistapa vähentää merkittävästi komentosarjan suoritusaikaa. Toinen vaihtoehto oli määrittää IIS käyttämään PHP:tä tilassa FastCGI. Tässä tapauksessa PHP-prosessi ei sulkeutunut valmistumisen jälkeen, vaan se sai uuden tehtävän seuraavan PHP-pyynnön yhteydessä. Lisäksi oli mahdollista ajaa useita PHP-prosesseja samanaikaisesti, mikä nopeutti huomattavasti pyyntöjen käsittelyä, mikä oli PHP CGI -tilan bonus. PHP-laajennuksissa on kuitenkin saattanut esiintyä pieniä yhteensopivuusongelmia. Tämä on edelleen nopein tapa käyttää PHP:tä, ja sitä varten IIS Aid PHP Installer on määritetty tekemään.

Sisään kerätyt binaarit säikeen vaarallinen tila (ei säiettä turvallista, NTS), voit määrittää IIS:n (ja muiden Windows-verkkopalvelimien) käyttämään PHP:tä tavallisena CGI-liittymänä, joka parantaa suorituskykyä, koska tässä tapauksessa (tällaisessa koontiversiossa) PHP-prosessin ei tarvitse odottaa säikeiden synkronointia. Kun verrataan "säikeen turvallisia" ja "säikeettömiä" PHP-binaaripaketteja IIS:ssä vakiona CGI-rajapinnana, suorituskyvyn kasvu on jopa 40 %, mutta tämä ei silti ole yhtä nopeaa kuin käytettäessä opkoodia FastCGI-menetelmässä. . Ja suurin ongelma on se, että säikeille vaarallisia binääritiedostoja ei voi luotettavasti käyttää yhdessä säikeen turvallisten binäärien kanssa. Tämä tarkoittaa, että et voi käyttää opkoodin välimuistijärjestelmiä, kuten eAccelerator, PHP-ympäristössä, joka on luotu säikeille vaarallisilla binääripaketilla (lauseke, joka on oikea kirjoitushetkellä).

Jos säikeille turvallista PHP:tä ei voida konfiguroida samaan nopeuteen kuin säieturvallista ympäristöä, miksi sitä tarvitaan tällaisessa koontiversiossa? Palataanpa FastCGI:n ja Microsoftin kehitykseen tällä alueella viime vuosina. Pienet-pehmeät koodaajat ovat luoneet oman versionsa FastCGI:stä, jonka avulla voit määrittää säikeille vaarallisia PHP-binaareja FastCGI-tilassa, mikä tuo suorituskykyä valonnopeuteen :)

Artikkelista päättelin, että jarrut havaitaan vain käytettäessä IIS-verkkopalvelimen kanssa. Joka tapauksessa en ole nähnyt typeriä asioita Windows+Apachen alla. Siinä sanotaan myös, että voit ylikellottaa NTS-kokoonpanon minkä tahansa web-palvelin, mutta en voi kuvitella sellaista Apache-asetusta.

Näyttää siltä, ​​​​että PHP-kehittäjät käyttävät harvoin samanaikaisuutta. En puhu synkronisen koodin yksinkertaisuudesta; yksisäikeinen ohjelmointi on tietysti yksinkertaisempaa ja selkeämpää, mutta joskus pieni rinnakkaisuuden käyttö voi parantaa suorituskykyä huomattavasti.

Tässä artikkelissa tarkastellaan, kuinka monisäikeinen voidaan saavuttaa PHP:ssä käyttämällä pthreads-laajennusta. Tämä vaatii PHP 7.x:n ZTS (Zend Thread Safety) -version asennettuna sekä pthreads v3 -laajennuksen asennettuna. (Kirjoitushetkellä PHP 7.1:ssä käyttäjien on asennettava päähaaroista pthreads-tietovaraston - katso kolmannen osapuolen laajennus.)

Pieni selvennys: pthreads v2 on tarkoitettu PHP 5.x:lle eikä sitä enää tueta, pthreads v3 on PHP 7.x:lle ja sitä kehitetään aktiivisesti.

Tällaisen poikkeaman jälkeen mennään suoraan asiaan!

Kertaluonteisten tehtävien käsittely

Joskus haluat käsitellä kertaluonteisia tehtäviä monisäikeisesti (esimerkiksi suorittaa I/O-sidottu tehtävä). Tällaisissa tapauksissa voit käyttää Thread-luokkaa luodaksesi uuden säikeen ja suorittaaksesi käsittelyä erillisessä säikeessä.

Esimerkiksi:

$tehtävä = uusi luokka laajentaa säiettä ( yksityinen $response; julkinen funktio run() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+)~", $sisältö, $osumat); $this->response = $osumia; ) ); $tehtävä->aloitus() && $tehtävä->liitty(); var_dump($tehtävä->vastaus); // merkkijono (6) "Google"

Tässä suoritusmenetelmä on meidän käsittelymme, joka suoritetaan uuden säikeen sisällä. Kun Thread::start kutsutaan, syntyy uusi säie ja ajomenetelmä kutsutaan. Yhdistämme sitten alasäikeen takaisin pääsäikeeseen kutsumalla Thread::join , joka estää, kunnes aliketju on suoritettu loppuun. Tämä varmistaa, että tehtävä päättyy ennen kuin yritämme tulostaa tuloksen (joka on tallennettu kohtaan $task->response).

Ei ehkä ole toivottavaa saastuttaa luokkaa virtalogiikkaan liittyvillä lisävastuilla (mukaan lukien vastuu ajomenetelmän määrittämisestä). Voimme erottaa tällaiset luokat perimällä ne säikeitetystä luokasta. Sitten ne voidaan ajaa toisen säikeen sisällä:

Luokkatehtävä laajentaa säikeitettyä ( julkinen $ vastaus; julkinen toiminto someWork() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+) ~", $content, $matches); $ this->response = $matches ) ) $tehtävä = uusi tehtävä; $thread = uusi luokka($tehtävä) laajentaa säiettä ( yksityinen $tehtävä; julkinen funktio __construct(Threaded $task) ( $this->task = $tehtävä; ) julkinen funktio run() ( $this->task->someWork( ) ) ); $säie->aloitus() && $säie->liitty(); var_dump($tehtävä->vastaus);

Mikä tahansa luokka, joka on suoritettava erillisessä säikeessä on pakko periä säikeitetyistä luokasta. Tämä johtuu siitä, että se tarjoaa tarvittavat ominaisuudet eri säikeiden käsittelyyn, sekä implisiittisen suojauksen ja hyödylliset rajapinnat (kuten resurssien synkronoinnin).

Katsotaanpa pthreads-laajennuksen tarjoamaa luokkahierarkiaa:

Kierre (toteuttaa Traversable, Collectable) Thread Worker Volatile Pool

Olemme jo käsitelleet ja oppineet Thread- ja Threaded-luokkien perusteet, katsotaanpa nyt kolmea muuta (Worker, Volatile ja Pool).

Lankojen uudelleenkäyttö

Uuden säikeen aloittaminen jokaiselle rinnakkaiskuvalle tehtävälle on melko kallista. Tämä johtuu siitä, että yhteinen-ei-mitään-arkkitehtuuri on otettava käyttöön psäikeissä monisäikeisyyden saavuttamiseksi PHP:ssä. Tämä tarkoittaa, että PHP-tulkin nykyisen ilmentymän koko suorituskonteksti (mukaan lukien jokainen luokka, käyttöliittymä, ominaisuus ja funktio) on kopioitava jokaista luotua säiettä varten. Koska tällä on huomattava vaikutus suorituskykyyn, striimiä tulee aina käyttää uudelleen aina kun mahdollista. Säikeitä voidaan käyttää uudelleen kahdella tavalla: käyttämällä Workersia tai käyttämällä pooleja.

Worker-luokkaa käytetään useiden tehtävien suorittamiseen synkronisesti toisessa säikeessä. Tämä tehdään luomalla uusi Worker-instanssi (joka luo uuden säikeen) ja työntämällä sitten tehtävät kyseisen erillisen säikeen pinoon (käyttäen Worker::pinoa).

Tässä pieni esimerkki:

Luokkatehtävä laajentaa säikeistettyä ( yksityinen $arvo; julkinen funktio __construct(int $i) ( $this->value = $i; ) julkinen funktio run() ( usleep(250000); echo "Tehtävä: ($this->value) \n"; ) ) $työntekijä = uusi Työntekijä(); $työntekijä->aloitus(); for ($i = 0; $i pino(new Task($i)); ) while ($työläinen->kerää()); $työntekijä->sammutus();

Yllä olevassa esimerkissä 15 tehtävää uudelle $worker-objektille työnnetään pinoon Worker::stack-metodin kautta ja ne käsitellään sitten työntöjärjestyksessä. Yllä näkyvää Worker::collect-menetelmää käytetään tehtävien puhdistamiseen heti, kun ne on suoritettu. Sillä, while-silmukan sisällä, estämme pääsäikeen, kunnes kaikki pinon tehtävät on suoritettu ja tyhjennetty - ennen kuin kutsumme Worker::shutdown -sovelluksen. Työntekijän irtisanominen aikaisin (eli silloin kun vielä on suoritettavaa tehtäviä) estää edelleen pääsäikeen, kunnes kaikki tehtävät ovat suorittaneet suorituksensa, vain siksi, että tehtäviä ei kerätä roskiin (mikä tarkoittaa muistivuotoja).

Worker-luokka tarjoaa useita muita menetelmiä, jotka liittyvät sen tehtäväpinoon, mukaan lukien Worker::unstack viimeisen pinotun tehtävän poistamiseen ja Worker::getStacked suorituspinon tehtävien määrän hankkimiseen. Työntekijäpino sisältää vain ne tehtävät, jotka on suoritettava. Kun pinossa oleva tehtävä on suoritettu, se poistetaan ja sijoitetaan erilliseen (sisäiseen) pinoon roskien keräämistä varten (käyttämällä Worker::collect -menetelmää).

Toinen tapa käyttää säiettä uudelleen useissa tehtävissä on käyttää säievarastoa (pool-luokan kautta). Säiepooli käyttää työntekijöiden ryhmää tehtävien suorittamisen mahdollistamiseksi samanaikaisesti, jossa samanaikaisuuskerroin (joiden poolin säikeiden lukumäärä, joiden kanssa se toimii) asetetaan poolia luotaessa.

Mukautetaan yllä olevaa esimerkkiä työntekijöiden joukkoon:

Luokkatehtävä laajentaa säikeistettyä ( yksityinen $arvo; julkinen funktio __construct(int $i) ( $this->value = $i; ) julkinen funktio run() ( usleep(250000); echo "Tehtävä: ($this->value) \n"; ) ) $pool = uusi Pool(4); for ($i = 0; $i lähetä(new Task($i)); ) while ($pool->collect()); $pool->shutdown();

Allasta ja työntekijää käytettäessä on muutamia merkittäviä eroja. Ensinnäkin poolia ei tarvitse käynnistää manuaalisesti, se alkaa suorittaa tehtäviä heti, kun ne tulevat saataville. Toiseksi me lähettää tehtäviä uima-altaalle, ei laita ne pinoon. Lisäksi Pool-luokka ei peri Threadedistä, joten sitä ei voida siirtää muille säikeille (toisin kuin Worker).

On hyvä käytäntö, että työntekijät ja poolit siivoavat aina tehtävänsä heti, kun he ovat saaneet päätökseen, ja lopettavat ne sitten manuaalisesti itse. Thread-luokalla luodut säikeet on myös liitettävä pääsäikeeseen.

psäikeet ja (ei)muuttumattomuus

Viimeinen luokka, johon puutumme, on Volatile, uusi lisäys pthreads v3:een. Muuttumattomuudesta on tullut tärkeä käsite p-säikeissä, koska ilman sitä suorituskyky kärsii merkittävästi. Siksi oletusarvoisesti säikeistetyt luokkien ominaisuudet, jotka ovat itse säikeistettyjä objekteja, ovat nyt muuttumattomia, eikä niitä siksi voida korvata alkuperäisen määrityksen jälkeen. Tällaisten ominaisuuksien eksplisiittinen muuntavuus on tällä hetkellä edullinen, ja se voidaan edelleen saavuttaa käyttämällä uutta Volatile-luokkaa.

Katsotaanpa esimerkkiä, joka osoittaa uudet muuttumattomuusrajoitukset:

Luokkatehtävä laajentaa säikeistettyä luokkaa (julkinen funktio __construct() ( $this->data = new Threaded(); // $this->data ei ole ylikirjoitettavissa, koska se on säikeitetyn luokan säikeistetty ominaisuus)) $task = new class(new Task()) laajentaa säiettä ( // säikeistetty luokka, koska säie laajentaa säikeen julkinen funktio __construct($tm) ( $this->threadedMember = $tm; var_dump($this->threadedMember-> data); // objekti(Threaded)#3 (0) () $this->threadedMember = new StdClass( // virheellinen, koska ominaisuus on säikeitetyn luokan jäsen ) );

Haihtuvien luokkien säikeiset ominaisuudet ovat toisaalta muuttuvia:

Luokkatehtävä laajentaa Volatilea ( julkinen funktio __construct() ( $this->data = new Threaded(); $this->data = new StdClass(); // kelvollinen, koska olemme haihtuvassa luokassa ) ) $tehtävä = uusi class(new Task()) laajentaa säiettä ( julkinen funktio __construct($vm) ( $this->volatileMember = $vm; var_dump($this->volatileMember->data); // objekti(stdClass)#4 (0) () // edelleen virheellinen, koska Volatile laajentaa Threaded, joten ominaisuus on edelleen säikeitetyn luokan jäsen $this->volatileMember = new StdClass() );

Voimme nähdä, että Volatile-luokka ohittaa ylätason Threaded-luokan asettaman muuttumattomuuden tarjotakseen mahdollisuuden muuttaa säikeitettyjä ominaisuuksia (sekä unset()).

On toinen keskustelunaihe, joka kattaa vaihtelevuuden ja haihtuvan luokan - taulukot. P-säikeissä taulukot lähetetään automaattisesti haihtuviin objekteihin, kun ne on määritetty säikeistetty-luokan ominaisuuteen. Tämä johtuu siitä, että useiden PHP-kontekstien joukon manipulointi ei yksinkertaisesti ole turvallista.

Katsotaanpa esimerkkiä uudelleen ymmärtääksemme joitain asioita paremmin:

$taulukko = ; $tehtävä = new class($array) laajentaa säiettä ( yksityinen $data; julkinen funktio __construct(array $array) ( $this->data = $array; ) public function run() ( $this->data = 4; $ tämä->tiedot = 5; print_r($this->data) ); $tehtävä->aloitus() && $tehtävä->liitty(); /* Lähtö: haihtuva objekti ( => 1 => 2 => 3 => 4 => 5) */

Näemme, että haihtuvia objekteja voidaan käsitellä ikään kuin ne olisivat taulukoita, koska ne tukevat taulukkotoimintoja, kuten (kuten yllä on esitetty) subset()-operaattori. Volatile-luokat eivät kuitenkaan tue perustaulukkofunktioita, kuten array_pop ja array_shift. Sen sijaan Threaded-luokka tarjoaa meille sellaiset toiminnot sisäänrakennetuina menetelminä.

Esittelynä:

$data = uusi luokka laajenee Haihtuva (julkinen $a = 1; julkinen $b = 2; julkinen $c = 3; ); var_dump($data); var_dump($data->pop()); var_dump($data->shift()); var_dump($data); /* Tulos: object(class@anonymous)#1 (3) ( ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) ) int(3) int(1) object(class@anonymous)#1 (1) ( ["b"]=> int(2) ) */

Muita tuettuja toimintoja ovat Threaded::chunk ja Threaded::merge .

Synkronointi

Tämän artikkelin viimeisessä osassa tarkastelemme synkronointia p-säikeissä. Synkronointi on menetelmä, jonka avulla voit hallita jaettujen resurssien käyttöä.

Toteutetaan esimerkiksi yksinkertainen laskuri:

$laskuri = uusi luokka laajentaa säiettä ( julkinen $i = 0; julkinen funktio run() ( for ($i = 0; $i i; ) ) ); $laskuri->aloitus(); for ($i = 0; $i i; ) $counter->join(); var_dump($laskuri->i); // tulostaa luvun 10-20

Ilman synkronointia lähtö ei ole deterministinen. Useat säikeet kirjoittavat samaan muuttujaan ilman valvottua pääsyä, mikä tarkoittaa, että päivitykset katoavat.

Korjataan tämä niin, että saadaan oikea tulos 20 lisäämällä ajoitus:

$laskuri = uusi luokka laajentaa säiettä ( public $i = 0; public function run() ( $this->synchronized(function () ( for ($i = 0; $i i; ) )); ) ); $laskuri->aloitus(); $laskuri->synkronoitu(funktio ($laskuri) ( for ($i = 0; $i i; ) ), $laskuri); $counter->join(); var_dump($laskuri->i); // int(20)

Synkronoidut koodilohkot voivat myös kommunikoida keskenään Threaded::wait- ja Threaded::notify- (tai Threaded::notifyAll) -menetelmillä.

Tässä on vaihtoehtoinen lisäys kahdessa synkronoidussa while-silmukassa:

$laskuri = uusi luokka laajentaa säiettä ( public $cond = 1; public function run() ( $this->synchronized(function ()) ( for ($i = 0; $i notify();); if ($this->cond === 1) ( $this->cond = 2; $this->wait(); ) ) ); $laskuri->aloitus(); $laskuri->synkronoitu(funktio ($laskuri) ( if ($laskuri->cond !== 2) ( $counter->wait(); // odota, että toinen alkaa ensin ) for ($i = 10; $i notify(); $counter->join(); /* Tulostus: 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) */

Saatat huomata lisäehtoja, jotka on asetettu Threaded::wait -puhelun ympärille. Nämä ehdot ovat kriittisiä, koska niiden avulla synkronoitu takaisinsoitto voi jatkua, kun se on vastaanottanut ilmoituksen ja määritetty ehto on tosi. Tämä on tärkeää, koska ilmoitukset voivat tulla muualtakin kuin silloin, kun Threaded::notify kutsutaan. Siten, jos kutsut Threaded::wait-metodille eivät olleet ehtojen sisällä, suoritamme vääriä herätyskutsuja, mikä johtaa arvaamattomaan koodin käyttäytymiseen.

Johtopäätös

Tarkastelimme pthreads-paketin viittä luokkaa (Threaded, Thread, Worker, Volatile ja Pool) ja kuinka kutakin luokkaa käytetään. Tarkastelimme myös uutta muuttumattomuuden käsitettä psäikeissä ja annoimme lyhyen yleiskatsauksen tuetuista synkronointiominaisuuksista. Kun nämä perusasiat ovat kunnossa, voimme nyt alkaa tutkia, kuinka psäikeitä voidaan käyttää tosielämän tapauksissa! Tämä on seuraavan postauksen aihe.

Jos olet kiinnostunut seuraavan postauksen käännöksestä, kerro minulle: kommentoi sosiaalisessa mediassa. verkostoissa, äänestä ja jaa viesti kollegoiden ja ystävien kanssa.

Joskus on tarpeen suorittaa useita toimintoja samanaikaisesti, esimerkiksi tarkistaa yhden tietokantataulukon muutokset ja tehdä muutoksia toiseen. Lisäksi jos jokin operaatioista (esimerkiksi muutosten tarkistaminen) vie paljon aikaa, on selvää, että peräkkäinen suoritus ei takaa resurssien tasapainottamista.

Tämän tyyppisen ongelman ratkaisemiseksi ohjelmointi käyttää monisäikeistystä - jokainen operaatio sijoitetaan erilliseen säikeeseen, johon on varattu määrä resursseja ja toimii sen sisällä. Tällä lähestymistavalla kaikki tehtävät suoritetaan erikseen ja itsenäisesti.

Vaikka PHP ei tue monisäikeistystä, sen emulointiin on useita menetelmiä, joista keskustellaan alla.

1. Useiden skriptin kopioiden suorittaminen - yksi kopio toimintoa kohden

//woman.php if (!isset($_GET["thread"])) ( system("wget"http://localhost/woman.php?thread=make_me_happy"); system("wget": http: //localhost/ woman.php?thread=tee_minua_rikas ) ( etsi_toinen_( ; )

Kun suoritamme tämän skriptin ilman parametreja, se suorittaa automaattisesti kaksi kopiota itsestään, operaatiotunnuksilla ("thread=make_me_happy" ja "thread=make_me_rich"), jotka käynnistävät tarvittavien toimintojen suorittamisen.

Näin saavutamme halutun tuloksen - kaksi operaatiota suoritetaan samanaikaisesti - mutta tämä ei tietenkään ole monisäikeistä, vaan yksinkertaisesti kainalosauva tehtävien suorittamiseen samanaikaisesti.

2. Jedin polku - PCNTL-laajennuksella

PCNTL on laajennus, jonka avulla voit työskennellä täysin prosessien kanssa. Hallinnan lisäksi se tukee viestien lähettämistä, tilan tarkistamista ja prioriteettien asettamista. Tältä edellinen PCNTL-skripti näyttää:

$pid = pcntl_fork(); if ($pid == 0) ( make_her_happy(); ) elseif ($pid > 0) ( $pid2 = pcntl_fork(); if ($pid2 == 0) ( etsi_toinen_yksi(); ) )

Se näyttää melko hämmentävältä, käydään se läpi rivi riviltä.

Ensimmäisellä rivillä "haarukkaamme" nykyisen prosessin (haarukka kopioi prosessia säilyttäen samalla kaikkien muuttujien arvot), jaamme sen kahteen rinnakkaiseen prosessiin (nykyinen ja lapsi).

Ymmärtääkseen, olemmeko tällä hetkellä lapsi- vai äitiprosessissa, pcntl_fork-funktio palauttaa 0:n lapselle ja prosessitunnuksen äidille. Siksi toisella rivillä katsomme $pid, jos se on nolla, niin olemme lapsiprosessissa - suoritamme funktiota, muuten olemme äidissä (rivi 4), sitten luomme toisen prosessin ja suorittaa tehtävän samalla tavalla.

Skriptin suoritusprosessi:

Siten komentosarja luo vielä 2 aliprosessia, jotka ovat sen kopioita ja sisältävät samat muuttujat samanlaisilla arvoilla. Ja käyttämällä pcntl_fork-funktion palauttamaa tunnistetta, selvitämme, missä säikeessä olemme tällä hetkellä, ja suoritamme tarvittavat toimenpiteet.