Çarəsiz müzakirə mövzusu php. Pthreads Tərcüməsi ilə PHP-də Çoxillik Proqramlaşdırma

Bu yaxınlarda pthreads cəhd etdim və xoş təəccübləndim - bu, PHP-də çoxlu real mövzularla işləmək qabiliyyətini əlavə edən genişlənmədir. Təqlid yoxdur, sehr yoxdur, saxtakarlıq yoxdur - hər şey realdır.



Mən belə bir tapşırığı düşünürəm. Tez yerinə yetirilməli olan bir sıra tapşırıqlar var. PHP-də bu problemi həll etmək üçün başqa alətlər var, onlar burada qeyd olunmur, məqalə pthreads haqqındadır.



pthreads nədir

Hamısı budur! Yaxşı, demək olar ki, hər şey. Əslində, maraqlanan oxucunu narahat edə biləcək bir şey var. Bunların heç biri standart seçimlərlə tərtib edilmiş standart PHP-də işləmir. Çoxişlilikdən həzz almaq üçün PHP-də ZTS (Zend Thread Safety) aktiv olmalıdır.

PHP quraşdırma

Sonra, ZTS ilə PHP. ZTS (37.65 vs 265.05 saniyə) olmayan PHP ilə müqayisədə icra müddətindəki böyük fərqə fikir verməyin, mən PHP quraşdırmasını ümumiləşdirməyə çalışmadım. ZTS olmayan halda, məsələn, XDebug-u aktivləşdirmişəm.


Gördüyünüz kimi, 2 ipdən istifadə edərkən, proqramın icra sürəti xətti kod vəziyyətindən təxminən 1,5 dəfə yüksəkdir. 4 ipdən istifadə edərkən - 3 dəfə.


Qeyd edə bilərsiniz ki, prosessor 8 nüvəli olsa da, 4-dən çox ipdən istifadə olunarsa, proqramın icra müddəti demək olar ki, dəyişməz qaldı. Deyəsən bu prosessorumun 4 fiziki nüvəsi olması ilə bağlıdır.Aydınlıq üçün lövhəni diaqram şəklində təsvir etmişəm.


Xülasə

PHP-də pthreads uzantısından istifadə edərək çox iş parçacığı ilə kifayət qədər zərif işləmək mümkündür. Bu, məhsuldarlığın nəzərəçarpacaq dərəcədə artmasına səbəb olur.

Teqlər: Teqlər əlavə edin

Mənim yaxşı dostumun anası Sankt-Peterburqdan Moskvaya uçarkən çamadanını itirdi və daha isti sahillərə uçdu və indi o, artıq kurortda idi - çimərlik paltarı, sandalsız və yalnız T ilə - əl yükündən köynək. Köhnə günlər üçün ona nə etməli və hara qaçmalı olduğuna dair bir neçə məsləhət verdim və bu gün müəyyən bir mövzuda bildiyim hər şeyi burada yazmağa qərar verdim.

Harada bu qədər ağıllı olduğumu izah etmək üçün sizə xatırlatmaq istərdim ki, bir vaxtlar bir neçə aviaşirkətin yerüstü xidmətlərində, o cümlədən baqaj axtarışı ilə bağlı müəyyən məsələlərlə məşğul olmuşam. Əlbətdə ki, üstəlik öz uçuş təcrübəm. Lakin, çünki Mən aviasiya xidməti sənayesini bir neçə il əvvəl tərk etdim, bəlkə də bəzi nüanslar dəyişə bilər - əgər belədirsə, mövzu ilə bağlı şərhləri minnətdarlıqla qəbul edəcəyəm və yazıdakı məlumatları düzəldəcəm.

Mən bununla başlayacağam Baqajınızın itməsinin qarşısını almaq üçün nə etməlisiniz:
1. Əvvəlki səfərlərə aid bütün etiketləri və stikerləri, hətta ştrix kodlu kiçik olanları belə, tez-tez çamadanın özünə ayrıca yapışdırıb çıxarın - onlar baqajın avtomatik skan edilməsi və çeşidlənməsi sistemini çaşdıra bilər.
2. Çamadanınıza ad etiketi (çanta, qutu, bağlama - ümumiyyətlə, baqaj kimi qeydiyyatdan keçirdiyiniz hər şey) asın: əvvəlcədən təkrar istifadə edilə bilən opsiya ala bilərsiniz və ya qeydiyyat masasında kağız etiket götürə bilərsiniz - adətən hamısı az-çox layiqli aviaşirkətlər onları məhdudiyyətsiz buraxırlar. Məsələn, Emirates, ümumiyyətlə, çox uzun müddət davam edə bilən davamlı şnurda əla plastik etiketlərə malikdir:

Köhnə paranoidlər də mənim kimi edə bilərlər: mənim həmişə çamadanımda daimi ev ünvanım, telefon nömrəm və e-poçtum olan Samsonite dəstindən təkrar istifadə oluna bilən plastik etiket var və mən tətildə harasa uçanda əlavə olaraq kağız asıram. yeni yerdə qaldığım tarixləri və bütün mümkün əlaqələri göstərin (mehmanxananın adı və ünvanı, əgər varsa, yerli telefon nömrəsi və əlbəttə ki, adınız və soyadınız).
3. Check-in kassasında qeydiyyat agenti tərəfindən çap edilmiş baqaj etiketinin baqajınıza yapışdırıldığından əmin olun - uçduğunuz şəhər kodu və uçuş nömrəsi ilə.
4. Əgər bir neçə birləşdirici uçuşunuz varsa, bu barədə qeydiyyat agentinə məlumat verin və baqajınızı hansı məntəqəyə qədər yoxlamaq istədiyinizi göstərin. Bəzi hallarda, istəyinizdən asılı olmayaraq, baqaj marşrut boyunca bu və ya digər hava limanında götürülməli olacaq: bu, məsələn, hava limanları arasında transferlərə aiddir (Parisdəki Orli və Şarl de Qoll, Domodedovo - Şeremetyevo - "Vnukovo" " Moskvada), ayrıca terminallar (Frankfurtdakı 1 və 2 terminallar) və ya ABŞ və ya Meksikaya ilk gəliş nöqtəsində - bu, bu ölkələrdə gömrük tələbidir: Moskva-Vaşinqton-Feniks, baqaj etiketi ilə uçursunuz. Phoenix-ə hər üç seqment üçün verilir, lakin Vaşinqtonda baqaj fiziki olaraq götürülməli, gömrükdən keçirilməli və yenidən yoxlanılmalıdır.Həmçinin, əgər siz gəmiyə minməzdən əvvəl götürməyə icazə verilmiş uşaq arabasında yoxlanırsınızsa təyyarə və ya heyvan, çox güman ki, onu tranzit nöqtəsindən götürməli olacaqsınız. Ümumiyyətlə, köçürmələri olan mürəkkəb bir marşrut vəziyyətində, baqaj hərəkətlərinin təfərrüatlarını əvvəlcədən aviaşirkətin zəng mərkəzində və ya həddindən artıq hallarda qeydiyyat zamanı dəqiqləşdirmək daha yaxşıdır.
5. Baqajınızı görünən edin: baqajın gecikdirilməsi həmişə baqaj idarəçilərinin günahı və ya çeşidləmə sistemindəki nasazlıqlar deyil. Bəzən uzun bir uçuşdan sonra yorğun olan başqa bir fikirsiz sərnişin baqaj karuselindən sizinki kimi eyni qara Samsonite və ya qeyri-adi idman çantasını götürəcəkdir. Buna görə də, baqajınızı qeyd edin: tutacaqda bir dəstə parlaq lent və ya kiçik yumşaq oyuncaq asın, üzərinə böyük bir stiker yapışdırın və ya çamadan seçərkən sadəcə olaraq qeyri-adi rəngə üstünlük verin.

Baqajda nələr yoxlanılmamalıdır?
Unutmayın ki, bütün aviaşirkətlər və hava limanları baqajlarını itirirlər. Əlbəttə ki, statistika hər kəs üçün fərqlidir, lakin hətta ən etibarlı aviaşirkətlər baqajı itirə və ya gecikdirə bilər, hətta ən kiçik hava limanında da bir baqaj işçisi çamadanları olan arabanı birbaşa qeydiyyat məntəqəsindən təyyarəyə daşıyacaq. Buna görə də sizə həmişə əl yükünüzü götürməyi məsləhət görürəm:
- vacib sənədlər, o cümlədən uçuş zamanı lazım olmayanlar (məsələn, Sankt-Peterburqa son səfərim zamanı lisenziyamı dəyişməli oldum və əl yükümdə nikah şəhadətnaməsi və hər cür kartlar götürdüm. sürücülük məktəbi)
- açarlar (ünvanınızı göstərən etiketlə birlikdə bu təhlükəli ola bilər)
- pul, zərgərlik (şərh yoxdur)
- bahalı kövrək avadanlıq
- mütəmadi olaraq qəbul etdiyiniz, uçuş üçün tələb olunan miqdarda və xarici ölkədə və ya şəhərdə analoq axtarmalı olduğunuz halda kiçik ehtiyatla qəbul etdiyiniz dərmanlar. Baqajınız itirildikdə almaq mümkün olmayan reseptlə verilən dərmanları bütün səyahət üçün lazım olan miqdarda özünüzlə aparın.
- gəldikdən sonra təcili ehtiyacınız ola biləcək bir şey (məsələn, telefon şarj cihazı
- şəxsən sizin üçün sentimental dəyəri olan bir şey: bəzən baqaj əbədi olaraq itirilir və şəxsi gündəliyinizi itirmək ürəyinizi parçalayırsa, onu evdə qoymağınız və ya təyyarədə özünüzlə aparmaq daha yaxşıdır.

Öyrənici bir hekayə: Sankt-Peterburqda Lufthansa-da işlədiyim müddətdə ABŞ-dan bir ər-arvad əllərini sıxaraq ofisimizə qaçaraq gəldilər - övladlığa götürmə məhkəməsi üçün çox vacib sənədləri olan baqajları gəlməmişdi, məhkəmə ertəsi gün idi. Təbii ki, baqajın itirilməsində aviaşirkət günahkardır, bəs bundan kimə sərfəli? Belə bir vəziyyətə düşməmək üçün sadəcə olaraq əl yükünüzə vacib sənədləri qoymaq kifayət idi.

Beləliklə, siz gəldiniz və baqajınızı baqaj kəmərində tapmadınız. Nə etməli?
1. Əgər baqajınızda adi çamadanlardan fərqli bir şey yoxlamısınızsa: xizəklər, violonçel, divar ölçülü plazma panel, uşaq arabası, canlı mərmər Böyük Dane, qondarmaların verilməsi üçün ayrıca bir nöqtənin olub olmadığını yoxlayın. böyük ölçülü baqaj və ya həcmli baqaj - yuxarıda təsvir etdiyimə bənzər baqaj çox vaxt ayrıca bölməyə yüklənir və ayrıca, əl ilə boşaldılır. Əgər baqajınız orada da tapılmırsa
2. Baqaj axtarışına və ya İtirilmiş və Tapılmış sayğacına keçin. Orada siz baqajınız haqqında ətraflı məlumatı əks etdirən xüsusi bir forma doldurmalısınız: marşrut, görünüş, məzmunun qısa siyahısı, daimi yaşayış yerinizdə və müvəqqəti qalma yerinizdəki əlaqələr. Həmçinin, baqaj izləmə xidmətində siz daha çox belə bir baqaj cədvəlini görürsünüz:

Məhz bu təsnifata uyğun olaraq itkin baqajınız kodlaşdırılacaq və başa düşdüyünüz kimi, bu iki çamadan eyni kodlaşdırılacaq:

Beləliklə, təsvirə əlavə təfərrüatlar əlavə etməkdən çekinmeyin və məzmun bəndini qaçırmayın. Bir qayda olaraq, baqajın gecikdirilməsi haqqında hesabatı ilk dəfə doldurduğunuz zaman sizdən xaricdə müəyyənedici işarələr olmadıqda və çantanın açılması tələb olunarsa, çantanızı müəyyən etmək üçün bir neçə məzmunu göstərməyiniz xahiş olunacaq (əgər çanta açılır, bu barədə bildiriş göndərəcəksiniz). Pis nümunə: köynək / kitab / nəm salfetlər, yaxşı nümunə: parlaq qırmızı bikini / Maleviç reproduksiyalarının kataloqu / qatlanan dəmir. Ərizəni doldurduqdan sonra baqajın axtarışı xidmətinin əməkdaşı sizə XXXYY11111 formatında nömrə verəcək, burada XXX gəliş hava limanı kodu, YY gəliş aviaşirkət kodu + proqramın seriya nömrəsinin 5 rəqəmi: məsələn, JFKLH12345, əgər Lufthansa ilə Nyu Yorkdakı Kennedi hava limanına uçmusunuz. Bu nömrəni yadda saxlayın və ya yazın - bu, gələcək tətbiqlərdə ərizənizi tapmaq üçün ən asan yol olacaq.
Eyni nömrədən istifadə edərək axtarış vəziyyətini ÖZÜNÜZ yoxlaya bilərsiniz (nədənsə link yox olur: əgər bu sizin üçün işləmirsə, google World Tracer Online və sözün əsl mənasında ikinci link - worldtracer.aero saytında Baqajın İzlənməsi başlığı ilə - sizə lazım olan şeydir), çünki itirilmiş və tapılmışdır. çox vaxt çox çətindir
3. Gəliş hava limanındakı aviaşirkətinizin ofisi ilə əlaqə saxlamağa çalışın: bəzən (vurğulayıram - BƏZƏN!) əgər siz evə yox, müvəqqəti qalacağınız yerə (məzuniyyət, ezamiyyət) getmisinizsə, aviaşirkət dəsti təqdim edə bilər. tualet ləvazimatları (Lufthansa-da var). böyük ölçülü köynək, diş fırçası və pastası, daraq, kiçik bağlama şampun və duş geli, bir paket paltaryuyan toz və s. daxildir) və ya kiçik xərclər üçün kiçik bir nağd ödəniş edin. spot (spot nağd ödəniş).

Bundan sonra nə olacaq?
Faylınız (AHL adlanan) mərkəzləşdirilmiş baqaj axtarış sisteminə (World Tracer) gedəcək. Bütün tələb olunmamış baqaj əşyaları, baqaj həyətinin bucaqlarında etiketsiz tapılmasından və ya baqaj kəmərində qalmasından asılı olmayaraq, eyni axtarış sisteminə düşür; bu əşyaların hər biri üçün XXXYY11111 formatında fayldır. də yaradılmışdır, yalnız fərqli bir alt tipdən - sözdə. əl hesabatı və ya OHD. AHL və OHD fayllarından məlumatlar üst-üstə düşərsə (soyadı, çamadanın təsviri, marşrut və s.), hər iki stansiya (baqajın itirilməsi barədə məlumat verildiyi və tələb olunmamış baqajın tapıldığı yer) bildiriş alacaq və sonra texnoloji məsələdir: təkrar yoxlama və müvəffəqiyyətli olarsa baqajı istədiyiniz şəhərə çatdırmaq. Təbii ki, burada çoxlu əl işləri də var - mesaj mübadiləsi, oxşar, lakin eyni olmayan çamadanların rədd edilməsi, üstəlik, bir neçə telefon zənglərinə cavab vermək - ümumiyyətlə, baqaj axtarışı xidmətinin əməkdaşları heç vaxt darıxmırlar.
Təxmini statistika: itirilmiş baqajın 90%-dən çoxu axtarışın ilk 3 günündə tapılır, 3%-i isə əbədi olaraq itirilir.
Sən nə edə bilərsən?
1. Əgər çatanda təcili ehtiyacınız olan hər hansı bir şeyi (diş fırçasından tutmuş iş kostyumuna qədər) almalısınızsa, sonradan kompensasiya almaq üçün qəbzlərinizi saxlamağınızdan əmin olun. Bununla belə, lazımsız bahalı alışlardan qaçınmalısınız, bunun səbəbini sonra izah edəcəyəm.
2. Təzə addımlardan sonra hər bir elementin rəngi, markası və təxmini dəyəri ilə ən müfəssəl məzmun siyahısını ideal olaraq ingilis dilində hazırlayın (əks halda aviaşirkətin əməkdaşı sistemə daxil olmaq üçün bu siyahını tərcümə etməli olacaq) ilə əlaqə saxlayın. aviaşirkət və göndərin Onlar bu siyahını alırlar və o, baqaj axtarış proqramına əlavə olunacaq. İlk 5 gün ərzində baqajın axtarışı gəliş hava limanı tərəfindən həyata keçirilir, sonra axtarış daşıyıcı aviaşirkətin öhdəsinə düşür (müraciət nömrəsində göstərilən aviaşirkət - JFKLH12345-i xatırlayırsınızmı?) və 21 gündən sonra siz son kompensasiya üçün müraciət edə bilər.
3. İtirilmiş baqaj haqqında arayış verildiyi tarixdən 21 gün keçsə də, o, tapılmamışdırsa, kompensasiya tələb etmək üçün daşıyıcı aviaşirkətlə əlaqə saxlayın. Səhv etmirəmsə, iddia müddəti 2 ildir, yəni. Zərər üçün iddia qaldırdığınız tarixdən iki il ərzində kompensasiya üçün müraciət edə bilərsiniz.

Kompensasiyanın ödənilməsi.
Kompensasiyanı ödəmək üçün ödəniş ərizəsi, uçuşu təsdiq edən sənədlər və baqajın itirilməsi faktı (otinq talonları, baqaj etiketləri, baqajın itirilməsi ilə bağlı iddia nömrəsi, ödəniş rekvizitləri) ilə aviaşirkətinizin nümayəndəliyi ilə əlaqə saxlamalısınız. Səhv etmirəmsə, Rusiya Federasiyasında təzminatla bağlı qərara qanuni olaraq 30 gün ərzində baxılmalıdır. Sizdən həmçinin məzmunun dəyərini hesablamağınız və mümkünsə, çamadanın və içindəki əşyaların alınması üçün qəbzləri təqdim etməyiniz xahiş oluna bilər (başa düşürəm ki, bu, əksər hallarda qeyri-realdır, lakin bu, prosedurun bir hissəsidir).
Əvvəllər ödənişlər yoxlanılan baqajın çəkisi əsasında həyata keçirilirdi - kiloqramı təxminən 20 dollar. Sonradan ödəniş sistemi dəyişdirildi və aviaşirkətlərin öhdəliyi 1000 şərti vahidlə məhdudlaşdırıldı (şərti vahidin dəyəri aviaşirkət daxilində hesablanır), bu mənim işlədiyim vaxt təxminən 1300 avroya uyğun gəlirdi. Bunlar. min Boliviya gecko dərisindən hazırlanmış və brilyantlarla doldurulmuş Louis Vuitton çamadanının alınması üçün qəbz gətirsəniz belə, 1300 avrodan çox pul qazanmayacaqsınız.

Görünür, PHP tərtibatçıları nadir hallarda paralellikdən istifadə edirlər. Sinxron kodun sadəliyi haqqında danışmayacağam; tək yivli proqramlaşdırma, əlbəttə ki, daha sadə və aydındır, lakin bəzən paralellikdən bir az istifadə performansda nəzərəçarpacaq artım gətirə bilər.

Bu yazıda biz pthreads genişlənməsindən istifadə etməklə PHP-də çoxilliklərin necə əldə oluna biləcəyinə nəzər salacağıq. Bunun üçün quraşdırılmış pthreads v3 genişləndirilməsi ilə birlikdə PHP 7.x-in ZTS (Zend Thread Safety) versiyasının quraşdırılması tələb olunacaq. (Yazı zamanı PHP 7.1-də istifadəçilər pthreads repozitoriyasında master filialından quraşdırmalı olacaqlar - üçüncü tərəf uzantısına baxın.)

Kiçik bir izahat: pthreads v2 PHP 5.x üçün nəzərdə tutulub və artıq dəstəklənmir, pthreads v3 PHP 7.x üçündir və fəal şəkildə inkişaf etdirilir.

Belə bir kənarlaşmadan sonra gəlin birbaşa mətləbə keçək!

Birdəfəlik tapşırıqların işlənməsi

Bəzən siz birdəfəlik tapşırıqları çox yivli şəkildə emal etmək istəyirsiniz (məsələn, bəzi I/O ilə bağlı tapşırıqları yerinə yetirməklə). Belə hallarda siz Thread sinfindən istifadə edərək yeni başlıq yarada və ayrı bir mövzuda bəzi emal apara bilərsiniz.

Misal üçün:

$task = yeni sinif Mövzunu genişləndirir ( şəxsi $cavab; ictimai funksiya run() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+)~", $content, $matches); $this->cavab = $matches; ) ); $task->start() && $task->join(); var_dump($task->response); // string (6) "Google"

Burada run metodu bizim emalımızdır, hansı ki, yeni başlıq daxilində icra olunacaq. Thread::start çağırıldıqda yeni başlıq yaranır və run metodu çağırılır. Sonra Thread::join çağıraraq uşaq mövzunu yenidən əsas ipə birləşdiririk, bu, uşaq ipin icrasını bitirənə qədər bloklanacaq. Bu, nəticəni çap etməyə çalışmazdan əvvəl tapşırığın icrasını başa çatdırmasını təmin edir (bu, $task->cavabda saxlanılır).

Bir sinfi axın məntiqi ilə əlaqəli əlavə öhdəliklərlə (bir qaçış metodunun müəyyən edilməsi məsuliyyəti də daxil olmaqla) çirkləndirmək arzuolunmazdır. Bu cür sinifləri Threaded sinfindən miras alaraq ayıra bilərik. Sonra onlar başqa bir ipin içərisində işlədilə bilər:

Sinif Tapşırığı Threaded-i genişləndirir ( ictimai $response; ictimai funksiya someWork() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+) ~", $content, $matches); $ this->cavab = $uyğunluq; ) ) $task = yeni Tapşırıq; $thread = new class($task) Mövzunu genişləndirir ( şəxsi $task; ictimai funksiya __construct(Treaded $task) ( $this->task = $task; ) public function run() ( $this->task->someWork() ); ) ); $thread->start() && $thread->join(); var_dump($task->cavab);

Ayrı bir mövzuda işlədilməli olan hər hansı bir sinif lazımdır Threaded sinfindən miras alın. Bunun səbəbi, müxtəlif mövzularda emal etmək üçün lazımi imkanları, həmçinin gizli təhlükəsizlik və faydalı interfeysləri (məsələn, resurs sinxronizasiyası) təmin etməsidir.

Gəlin pthreads uzantısının təklif etdiyi sinif iyerarxiyasına nəzər salaq:

Yivli (Traversable, Collectable) Thread Worker Volatile Pool

Biz artıq Thread və Threaded siniflərinin əsaslarını əhatə etdik və öyrəndik, indi gəlin digər üçünə (İşçi, Uçucu və Hovuz) nəzər salaq.

Mövzuların təkrar istifadəsi

Paralelləşdirilməli olan hər bir tapşırıq üçün yeni mövzuya başlamaq kifayət qədər baha başa gəlir. Bunun səbəbi, PHP daxilində çox iş parçacığına nail olmaq üçün pthreads-də ümumi-heç bir arxitektura tətbiq edilməlidir. Bu o deməkdir ki, PHP tərcüməçisinin cari nümunəsinin bütün icra konteksti (hər sinif, interfeys, əlamət və funksiya daxil olmaqla) yaradılmış hər bir ip üçün kopyalanmalıdır. Bunun nəzərəçarpacaq performans təsirinə malik olduğu üçün axın həmişə mümkün olduqda təkrar istifadə edilməlidir. Mövzular iki şəkildə təkrar istifadə edilə bilər: İşçilərdən və ya Hovuzlardan istifadə etməklə.

İşçi sinfi bir sıra tapşırıqları sinxron olaraq başqa bir mövzu daxilində yerinə yetirmək üçün istifadə olunur. Bu, yeni İşçi nümunəsi yaratmaqla (yeni mövzu yaradır) və sonra tapşırıqları həmin ayrı mövzu yığınına itələməklə (İşçi:: yığınından istifadə etməklə) edilir.

Budur kiçik bir nümunə:

Sinif Tapşırığı Yivli ( şəxsi $value; ictimai funksiya __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Task: ($this->value) \n"; ) ) $işçi = yeni İşçi(); $işçi->start(); üçün ($i = 0; $i yığını(yeni Tapşırıq($i)); ) while ($işçi->toplama()); $worker->sutdown();

Yuxarıdakı misalda yeni $worker obyekti üçün 15 tapşırıq Worker::stack metodu ilə yığına itələnir və sonra onlar itələndikləri ardıcıllıqla işlənir. İşçi::toplama metodu, yuxarıda göstərildiyi kimi, tapşırıqların icrasını bitirən kimi onları təmizləmək üçün istifadə olunur. Bununla, bir müddət döngəsi içərisində, yığındakı bütün tapşırıqlar tamamlanana və təmizlənənə qədər əsas ipi bloklayırıq - biz Worker::shutdown çağırmadan əvvəl. İşçini vaxtından əvvəl dayandırmaq (yəni hələ tamamlanmalı olan tapşırıqlar olsa da) bütün tapşırıqlar icrasını tamamlayana qədər əsas mövzunu bloklayacaq, sadəcə olaraq, tapşırıqlar zibil yığılmayacaq (bu, yaddaş sızması deməkdir).

İşçi sinfi son yığılmış tapşırığı silmək üçün Worker::unstack və icra yığınında tapşırıqların sayını əldə etmək üçün Worker::getStacked daxil olmaqla, tapşırıq yığını ilə bağlı bir neçə başqa üsul təqdim edir. İşçi yığını yalnız yerinə yetirilməli olan tapşırıqları ehtiva edir. Yığındakı tapşırıq yerinə yetirildikdən sonra o, çıxarılır və zibil toplamaq üçün ayrıca (daxili) yığına yerləşdirilir (İşçi::toplama metodundan istifadə etməklə).

Birdən çox tapşırıqda ipdən təkrar istifadə etməyin başqa bir yolu ip hovuzundan istifadə etməkdir (Pool sinfi vasitəsilə). İplik hovuzu tapşırıqların icrasını təmin etmək üçün bir qrup İşçidən istifadə edir eyni vaxtda, hovuz yaradılarkən paralellik əmsalı (birlikdə işlədiyi hovuz iplərinin sayı) təyin olunur.

Yuxarıdakı nümunəni işçilər hovuzundan istifadə etmək üçün uyğunlaşdıraq:

Sinif Tapşırığı Yivli ( şəxsi $value; ictimai funksiya __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Task: ($this->value) \n"; ) ) $hovuz = yeni Hovuz(4); üçün ($i = 0; $i təqdim edirəm(yeni Tapşırıq($i)); ) while ($pool->toplama()); $pool->sutdown();

Bir işçidən fərqli olaraq hovuzdan istifadə edərkən bir neçə diqqətəlayiq fərq var. Birincisi, hovuzun əl ilə işə salınmasına ehtiyac yoxdur; o, tapşırıqlar əlçatan olan kimi icra etməyə başlayır. İkincisi, biz göndər hovuza tapşırıqlar deyil onları bir yığına qoyun. Bundan əlavə, Pool sinfi Threaded-dən miras alınmır və buna görə də digər mövzulara ötürülə bilməz (İşçidən fərqli olaraq).

İşçilərin və hovuzların tapşırıqlarını yerinə yetirən kimi həmişə təmizləmələri və sonra onları əl ilə dayandırmaları yaxşı təcrübədir. Thread sinfindən istifadə etməklə yaradılan mövzular da ana ipə əlavə edilməlidir.

pthreads və (im) dəyişkənlik

Toxunacağımız sonuncu sinif pthreads v3-ə yeni əlavə olan Uçucudur. Dəyişməzlik pthreads-də vacib bir anlayışa çevrildi, çünki onsuz performans əhəmiyyətli dərəcədə azalır. Buna görə də, standart olaraq, Threaded siniflərinin özləri Threaded obyektləri olan xassələri indi dəyişməzdir və buna görə də onların ilkin təyinatından sonra onların üzərinə yazıla bilməz. Bu cür xüsusiyyətlər üçün açıq-aşkar dəyişkənliyə üstünlük verilir və hələ də yeni Uçucu sinifdən istifadə etməklə əldə edilə bilər.

Yeni dəyişməzlik məhdudiyyətlərini nümayiş etdirəcək bir nümunəyə baxaq:

Sinif Tapşırığı Threaded-i genişləndirir // Yivli sinif ( ictimai funksiya __construct() ( $this->data = new Threaded(); // $this->data Threaded sinfinin Threaded xüsusiyyəti olduğu üçün üzərinə yazıla bilməz ) ) $task = new class(new Task()) Thread-ı genişləndirir ( // Yivli sinif, çünki Thread Threaded ictimai funksiyasını genişləndirir __construct($tm) ( $this->threadedMember = $tm; var_dump($this->threadedMember-> data); // object(Threaded)#3 (0) () $this->threadedMember = new StdClass(); // etibarsızdır, çünki xassə Threaded sinifinin Threaded üzvüdür ) );

Uçucu siniflərin yivli xassələri isə dəyişkəndir:

Sinif Tapşırığı Uçucunu genişləndirir ( ictimai funksiya __construct() ( $this->data = new Threaded(); $this->data = new StdClass(); // etibarlıdır, çünki biz uçucu sinifdəyik ) ) $task = new class(new Task()) Mövzunu genişləndirir ( ictimai funksiya __construct($vm) ( $this->volatileMember = $vm; var_dump($this->volatileMember->data); // object(stdClass)#4 (0) () // hələ də etibarsızdır, çünki Volatile Threaded-i genişləndirir, ona görə də xassə hələ də Yivli sinifin Yivli üzvüdür $this->volatileMember = new StdClass(); ) );

Görə bilərik ki, Volatile sinfi Threaded xassələrini dəyişdirmək imkanı təmin etmək üçün əsas Threaded sinfi tərəfindən qoyulmuş dəyişməzliyi ləğv edir (həmçinin unset()).

Dəyişkənlik və Uçucu sinif mövzusunu əhatə edən başqa bir müzakirə mövzusu var - massivlər. Pthreads-də massivlər Threaded sinifinin xassəsinə təyin olunduqda avtomatik olaraq Uçucu obyektlərə ötürülür. Bunun səbəbi, çoxsaylı PHP kontekstlərinin bir sırasını manipulyasiya etmək sadəcə təhlükəsiz deyil.

Bəzi şeyləri daha yaxşı başa düşmək üçün bir nümunəyə yenidən baxaq:

$massiv =; $task = new class($array) Mövzunu genişləndirir ( şəxsi $data; ictimai funksiya __construct(array $array) ( $this->data = $array; ) public function run() ( $this->data = 4; $ this->data = 5; print_r($this->data); ) ); $task->start() && $task->join(); /* Çıxış: Uçucu Obyekt ( => 1 => 2 => 3 => 4 => 5) */

Biz görürük ki, Uçucu obyektlərə massiv kimi baxıla bilər, çünki onlar (yuxarıda göstərildiyi kimi) subset() operatoru kimi massiv əməliyyatlarını dəstəkləyir. Bununla belə, Uçucu siniflər array_pop və array_shift kimi əsas massiv funksiyalarını dəstəkləmir. Bunun əvəzinə Threaded sinfi bizə daxili metodlar kimi əməliyyatları təqdim edir.

Nümayiş olaraq:

$data = yeni sinif Uçucunu genişləndirir ( ictimai $a = 1; ictimai $b = 2; ictimai $c = 3; ); var_dump($data); var_dump($data->pop()); var_dump($data->shift()); var_dump($data); /* Çıxış: obyekt(class@anonim)#1 (3) ( ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) ) int(3) int(1) obyekt(class@anonim)#1 (1) ( ["b"]=> int(2) ) */

Digər dəstəklənən əməliyyatlara Threaded::chunk və Threaded::merge daxildir.

Sinxronizasiya

Bu məqalənin son bölməsində pthreads-də sinxronizasiyaya baxacağıq. Sinxronizasiya paylaşılan resurslara girişi idarə etməyə imkan verən bir üsuldur.

Məsələn, sadə sayğac tətbiq edək:

$counter = yeni sinif Mövzunu genişləndirir ( ictimai $i = 0; ictimai funksiya run() ( üçün ($i = 0; $i i; ) ) ); $counter->start(); üçün ($i = 0; $i i; ) $counter->join(); var_dump($counter->i); // 10-dan 20-yə qədər rəqəm çap edəcək

Sinxronizasiyadan istifadə etmədən çıxış deterministik deyil. Birdən çox başlıq nəzarət edilən giriş olmadan eyni dəyişənə yazır, yəni yeniləmələr itiriləcək.

Gəlin bunu düzəldək ki, vaxtı əlavə etməklə 20-nin düzgün çıxışını əldə edək:

$counter = yeni sinif Mövzunu genişləndirir ( ictimai $i = 0; ictimai funksiya run() ( $this->sinxronlaşdırılmış(funksiya () ( ($i = 0; $i i; ) ); ) ); $counter->start(); $counter->sinxronlaşdırılmış(funksiya ($counter) ( üçün ($i = 0; $i i; ) ), $counter); $counter->qoşulmaq(); var_dump($counter->i); // int(20)

Sinxronlaşdırılmış kod blokları həmçinin Threaded::wait və Threaded::notify (və ya Threaded::notifyAll) metodlarından istifadə edərək bir-biri ilə əlaqə saxlaya bilər.

Budur, iki sinxronlaşdırılmış while döngəsində alternativ artım:

$counter = yeni sinif Mövzunu genişləndirir ( ictimai $cond = 1; ictimai funksiya run() ( $this->sinxronlaşdırılmış(funksiya () ( üçün ($i = 0; $i bildiriş(); əgər ($this->cond) === 1) ( $this->cond = 2; $this->wait(); ) ))) ); ) ); $counter->start(); $counter->synchronized(funksiya ($counter) ( if ($counter->cond !== 2) ( $counter->wait(); // birinci başqasının başlamasını gözləyin ) üçün ($i = 10; $i notify(); if ($counter->cond === 2) ( $counter->cond = 1; $counter->wait(); ) ) ), $counter); $counter->qoşulmaq(); /* Çıxış: 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) */

Siz Threaded::wait zəngi ətrafında əlavə şərtlərin olduğunu görə bilərsiniz. Bu şərtlər kritikdir, çünki onlar bildiriş qəbul etdikdə və göstərilən şərt doğru olduqda sinxronlaşdırılmış geri çağırışın davam etdirilməsinə imkan verir. Bu vacibdir, çünki bildirişlər Threaded::notify çağırıldığından başqa yerlərdən gələ bilər. Beləliklə, Threaded::wait metoduna edilən zənglər şərtlərə daxil edilməmişdirsə, biz icra edəcəyik yalançı oyanma zəngləri, bu, gözlənilməz kod davranışına səbəb olacaq.

Nəticə

Biz pthreads paketinin beş sinfinə (Threaded, Thread, Worker, Volatile və Pool) və hər bir sinfin necə istifadə edildiyinə baxdıq. Biz həmçinin pthreads-də yeni dəyişməzlik konsepsiyasına nəzər saldıq və dəstəklənən sinxronizasiya imkanları haqqında qısa məlumat verdik. Bu əsasları yerinə yetirməklə, indi pthreadların real dünya vəziyyətlərində necə istifadə oluna biləcəyinə baxa bilərik! Bu, növbəti yazımızın mövzusu olacaq.

Növbəti yazının tərcüməsi ilə maraqlanırsınızsa, mənə bildirin: sosial mediada şərh yazın. şəbəkələrdə səs verin və postu həmkarlarınız və dostlarınızla paylaşın.

Yivli müzakirə

A mövzulu müzakirə proqram təminatının mesajları vizual olaraq qruplaşdırmaqla istifadəçiyə yardım etdiyi elektron müzakirədir (məsələn, e-poçt, e-poçt siyahısı, bülleten lövhəsi, xəbər qrupu və ya İnternet forumu vasitəsilə). Mesajlar adətən mövzuya görə vizual olaraq iyerarxiyada qruplaşdırılır. Bu şəkildə qruplaşdırılmış mesajlar toplusu a adlanır mövzu mövzusu və ya sadəcə "iplik". Müzakirə forumu, e-poçt müştərisi və ya xəbər müştərisi eyni mövzuya aid mesajları bu şəkildə asan oxumaq üçün bir yerdə qruplaşdırarsa, "məvzuları" olduğu deyilir. Bundan əlavə, yivli müzakirələr adətən istifadəçilərə mövzunun mövzu daxilində xüsusi göndərişlərə cavab verməyə imkan verir. Nəticədə mövzu daxilində müzakirələr iyerarxiyası ola bilər. Müxtəlif proqram növləri bu iyerarxiyanın hansı mövzuda göstərilməsinə imkan verə bilər. Yivli rejim adlanır. (Alternativ kimin konkret kimə cavab verməsindən asılı olmayaraq, adətən bütün yazıları tarix sırası ilə göstərən Xətti Rejimdir.)

Üstünlüklər

İerarxik baxışların üstünlüyü ondan ibarətdir ki, onlar oxucuya söhbətin ümumi strukturunu tez bir zamanda qiymətləndirməyə imkan verir: xüsusilə kimin kimə cavab verdiyini. Beləliklə, xəbər qrupları kimi geniş söhbətlər və ya debatlar zamanı ən faydalıdır: həqiqətən də, həqiqətən mürəkkəb müzakirələr üçün, bir növ iyerarxik sistem olmadan arqumenti izləmək tez mümkünsüz olur.

Başqa bir fayda, iyerarxik yivli sistemlərdə cəmiyyətin daha incə qiymətləndirilməsidir. Müəyyən yazılara cavab verilməli olduğu kimi, konkret şəxslərə də cavab verilir. Buna görə də yivli söhbətlər yazıçının diqqətini cavablandırılan şəxsin spesifik baxışlarına və şəxsiyyətinə yönəldir. Bu, ən son şərhin ümumi hovuza daxil edildiyi forumlarda daha az baş verir.

Mənfi cəhətləri

İyerarxik yivlərin düz yivləmə ilə müqayisədə dezavantajı artan mürəkkəblik səviyyəsidir və buna görə də belə bir görünüş istifadəçilərdən yüksək səviyyəli rahatlıq və mürəkkəblik tələb edir. Buna görə də təəccüblü deyil ki, onun istifadəsinin Usenet, CIX və ya Slashdot kimi ən qədim və/yaxud ən mürəkkəb onlayn icmalarda ən ağır olması təəccüblü deyil. Veb söhbət və şərh sistemləri, müqayisədə, daha gəncdir və daha geniş auditoriyaya açıqdır və beləliklə, iyerarxik keçid yalnız bu yaxınlarda belə arenalarda adi hala çevrilir.

Ağac iyerarxiyasının tətbiqi həm də mövzu daxilində müzakirələrin parçalanmasına səbəb olur: bir neçə fərqli əvvəlki yazıya cavab verən və ya ümumiləşdirən mesaj göndərmək artıq mümkün olmur. Bunun əvəzinə, hər bir əvvəlki yazıya fərdi olaraq cavab verilməlidir. Bunun iyerarxik iplikdən istifadə edən forumlarda daha ziddiyyətli müzakirə tərzinə gətirib çıxardığı mübahisəlidir. Bununla belə, doğru olsa da, arzu olunan posta verilən cavabların həcminə görə birbaşa mövzulu cavab artıq mümkün deyilsə, istifadəçilər indi söhbəti davam etdirmək və davam etdirmək üçün tez-tez cavab verdikləri şəxsin sitatlarından istifadə edirlər. rəvan Bu, mesaj lövhəsinin bir çox icmaları tərəfindən mövzunun başqa hərtərəfli limitə çatması halında tövsiyə olunur.

Açıq mövzu

Açıq mövzu oxucuların seçdikləri hər hansı mövzunu şərh edə və müzakirə edə biləcəyi bir blog yazısına aiddir. Onlar adətən böyük miqdarda trafikə malik məşhur bloqlarda daha faydalıdır; Onlar tez-tez bloqun müəllifinin yazmaq üçün mövzusu olmadıqda və ya yerləşdirmədə sakitlik olduqda istifadə olunur.

Açıq mövzular həm də bloqların əsas səhifələrindəki yazıların monotonluğunu aradan qaldırmaq üçün istifadə olunur. Şərhlər məzmun yönümlü yazılarda yarana bilər; buna görə də, müəlliflər açıq mövzulardan istifadə edirlər ki, səhifə yüklənmə vaxtları yavaşlamasın.

Nümunələr

*Yahoo! Qruplar [ http://groups.yahoo.com/], MSN Qrupları [ http://groups.msn.com/] və Slashdot [ http://www.slashdot.com/] hamısı yivli müzakirələri əks etdirən veb əsaslı forumlar təklif edir.

Həmçinin bax

*Elmi Skywriting
* Bloq şərtlərinin siyahısı

İstinadlar

*Dartmut. (2003). [ http://www.dartmouth.edu/~webteach/articles/discussion.html "Onlayn müzakirələrin aparılması" ]
*Wolsey, T. DeVere, [ http://www.readingonline.org/articles/art_index.asp?HREF=wolsey/index.html "Kiberməkanda ədəbiyyat müzakirəsi: Gənc yeniyetmələr kitablar haqqında danışmaq üçün mövzulu müzakirə qruplarından istifadə edir.]. "Onlayn oxumaq", 7(4), yanvar/fevral 2004. Alındı ​​30 dekabr 2007

Wikimedia Fondu. 2010.

  • Leon Powe
  • Barh Azoum

Digər lüğətlərə baxın:

    İnternet forumu- Ən məşhur forum paketlərindən biri olan phpBB İnternet Forumu proqram paketi... Wikipedia

    Virtual öyrənmə mühitlərinin tarixi 1990-cı illər- Virtual öyrənmə mühitlərinin tarixində, 1990-cı illər, ilk növbədə, əlverişli kompüterin və İnternetin meydana çıxması ilə əlaqədar inkişaf dövrü idi.1990-cı illər1990* Formal Systems Inc. Princeton, NJ, ABŞ DOS əsaslı Qiymətləndirmə təqdim edir… … Vikipediya

    QƏHƏ- Birgə Üz-üzə Təhsil Mühiti Tərtibatçı(lar)ı LEAD konsorsiumu Stabil buraxılış 5.0 / İyun 2010 Əməliyyat sistemi Çarpaz platforma … Wikipedia

    Söhbət ipliyi- bir çox e-poçt müştəriləri, bülleten lövhələri, xəbər qrupları və ya İnternet forumları tərəfindən istifadə edilən bir xüsusiyyətdir və proqram təminatı mesajları vizual olaraq qruplaşdırmaqla istifadəçiyə kömək edir. Mesajlar adətən mövzuya görə vizual olaraq iyerarxiyada qruplaşdırılır. Qruplaşdırılmış mesajlar toplusu... ... Vikipediya

    Slashdot- Nerdlər üçün Slashdot.org əsas səhifəsinin URL slashdot.org Sloqan Xəbərinin ekran görüntüsü. Əhəmiyyətli şeylər... Vikipediya

    MediaViki- ad sahəsi burada yönləndirilir. Vikipediyada MediaWiki ad sahəsi ilə bağlı yardım üçün Yardım:MediaWiki ad sahəsinə baxın. Vikipediya ad məkanları haqqında ümumi məlumat üçün Vikipediya:Ad sahəsinə baxın. Müzakirə səhifəsi və MediaWiki müzakirə səhifəsi bura yönləndirilir. Üçün... ... Vikipediya

    Kompüter vasitəsilə əlaqə- Digər istifadələr üçün CMC-yə (anlam ayrımı) baxın. Kompüter vasitəçiliyi rabitəsi (CMC) iki və ya daha çox şəbəkəyə qoşulmuş kompüterlərin istifadəsi ilə baş verən hər hansı bir kommunikativ əməliyyat kimi müəyyən edilir. Termin ənənəvi olaraq həmin… … Vikipediyaya aiddir

    Wiki proqram təminatının müqayisəsi- Aşağıdakı cədvəllər bir sıra viki proqram paketləri üçün ümumi və texniki məlumatları müqayisə edir. Məzmun 1 Ümumi məlumat 2 Hədəf auditoriyası 3 Xüsusiyyətlər 1 4 Xüsusiyyətlər 2 … Vikipediya

    Elmi Skywriting- koqnitiv alim Stevan Harnad tərəfindən hazırlanmış bir termindir və çoxlu e-poçtun və xəbər qrupu, elektron poçt siyahısı, hipermail, netnews və ya İnternet forumu kimi mövzu ilə əlaqəli veb arxivin birləşməsini təsvir edir, əlaqəli və tarixə görə çeşidlənir,… … Wikipedia

    Birgə qərar qəbul etmə proqramı- Birgə qərarların qəbulu (CDM) proqramı bütün müvafiq maraqlı tərəflərin prosesdə iştirakına imkan verən, vaxtında kollektiv qərarlar qəbul etmək üçün tələb olunan funksiyaları və xüsusiyyətləri koordinasiya edən proqram təminatı tətbiqi və ya moduludur. The... ... Vikipediya

Bəzən eyni vaxtda bir neçə hərəkəti yerinə yetirmək lazım olur, məsələn, bir verilənlər bazası cədvəlində dəyişiklikləri yoxlamaq və digərinə dəyişikliklər etmək. Üstəlik, əməliyyatlardan biri (məsələn, dəyişikliklərin yoxlanılması) çox vaxt aparırsa, ardıcıl icranın resurs balansını təmin etməyəcəyi açıqdır.

Bu cür problemi həll etmək üçün proqramlaşdırma multithreading istifadə edir - hər bir əməliyyat ayrılmış miqdarda resurs ilə ayrıca bir ipə yerləşdirilir və onun daxilində işləyir. Bu yanaşma ilə bütün tapşırıqlar ayrıca və müstəqil şəkildə yerinə yetiriləcəkdir.

Baxmayaraq ki, PHP çox iş parçacığını dəstəkləmir, onu təqlid etmək üçün bir neçə üsul var ki, bunlar aşağıda müzakirə olunacaq.

1. Skriptin bir neçə nüsxəsini işlətmək - hər əməliyyat üçün bir nüsxə

//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["thread"] == "məni_xoşbəxt etmək") ( make_her_happy(); ) elseif ($_GET["thread"] == "məni_zəngin etmək" ) (başqasını_tap( ); )

Bu skripti parametrlərsiz icra etdikdə, o, avtomatik olaraq iki nüsxəsini işlədir, əməliyyat identifikatorları ilə (“thread=make_me_happy” və “thread=make_me_rich”) lazımi funksiyaların icrasına başlayır.

Beləliklə, biz istədiyiniz nəticəyə nail oluruq - iki əməliyyat eyni vaxtda həyata keçirilir - lakin bu, əlbəttə ki, çox iş parçacığı deyil, sadəcə olaraq eyni vaxtda tapşırıqları yerinə yetirmək üçün bir qoltuqaltıdır.

2. Jedi-nin yolu - PCNTL uzantısından istifadə etməklə

PCNTL, proseslərlə tam işləməyə imkan verən bir uzantıdır. İdarəetmə ilə yanaşı, mesajların göndərilməsini, statusun yoxlanılmasını və prioritetlərin təyin edilməsini dəstəkləyir. PCNTL istifadə edən əvvəlki skript belə görünür:

$pid = pcntl_fork(); if ($pid == 0) ( make_her_happy(); ) elseif ($pid > 0) ( $pid2 = pcntl_fork(); if ($pid2 == 0) (başqa_birini tap(); ) )

Olduqca çaşqın görünür, gəlin onu sətir-sətir keçirək.

Birinci sətirdə biz cari prosesi “çəngəlləyirik” (çəngəl bütün dəyişənlərin dəyərlərini qoruyaraq prosesi kopyalayır), onu paralel olaraq işləyən iki prosesə (cari və uşaq) bölürük.

Hazırda uşaq və ya ana prosesində olduğumuzu anlamaq üçün pcntl_fork funksiyası uşaq üçün 0, ana üçün proses identifikatoru qaytarır. Buna görə də ikinci sətirdə $pid-ə baxırıq, əgər sıfırdırsa, onda biz uşaq prosesindəyik - funksiyanı yerinə yetiririk, əks halda biz anadayıq (sətir 4), sonra başqa bir proses yaradırıq və eyni şəkildə tapşırığı yerinə yetirin.

Skript icra prosesi:

Beləliklə, skript onun nüsxələri olan və oxşar dəyərlərə malik eyni dəyişənləri ehtiva edən daha 2 uşaq prosesi yaradır. Və pcntl_fork funksiyası tərəfindən qaytarılan identifikatordan istifadə edərək, hazırda hansı ipdə olduğumuzu tapırıq və lazımi hərəkətləri edirik.



Əlaqədar nəşrlər