aşk tartışma konu php. Pthreads Çevirisi ile Çok İş parçacıklı PHP Programlama. Tek seferlik görevleri işleme

  • 03.11.2019
  • programlama,
  • paralel programlama
  • Geçenlerde pthreads denedim ve hoş bir sürpriz oldu - bu, PHP'ye birkaç gerçek iş parçacığıyla çalışma yeteneği ekleyen bir uzantıdır. Öykünme yok, sihir yok, sahte yok - her şey gerçek.



    Bu konuya bakıyorum. Hızlı bir şekilde tamamlanması gereken bir görev havuzu var. PHP'de bu sorunu çözmek için başka araçlar da var, burada bahsedilmiyor, makale pthreads hakkında.



    pthreads nedir

    Bu kadar! Neredeyse her şey. Aslında, meraklı okuyucuyu üzebilecek bir şey var. Bunların hiçbiri, varsayılan seçeneklerle derlenmiş standart PHP üzerinde çalışmaz. Çoklu okumanın keyfini çıkarmak için PHP'nizde ZTS'nin (Zend Thread Safety) etkinleştirilmiş olması gerekir.

    PHP kurulumu

    Ardından, ZTS ile PHP. ZTS'siz PHP ile karşılaştırıldığında (37.65'e karşı 265.05 saniye) yürütme süresindeki bu kadar büyük bir farkı görmezden gelin, PHP kurulumunu genelleştirmeye çalışmadım. ZTS'siz durumda, örneğin XDebug'u etkinleştirdim.


    Gördüğünüz gibi, 2 iş parçacığı kullanıldığında, program yürütme hızı, doğrusal kod durumundan yaklaşık 1,5 kat daha yüksektir. 4 iplik kullanırken - 3 kez.


    İşlemci 8 çekirdekli olmasına rağmen, 4'ten fazla iş parçacığı kullanıldığında program yürütme süresinin neredeyse değişmediğini fark edebilirsiniz. Görünüşe göre bu, işlemcimin 4 fiziksel çekirdeğe sahip olmasından kaynaklanıyor.Netlik için bir plakayı diyagram şeklinde tasvir ettim.


    Özet

    PHP, pthreads uzantısını kullanarak oldukça şık çoklu kullanım sağlar. Bu, gözle görülür bir performans artışı sağlar.

    Etiketler:

    • php
    • pthreads
    Etiket ekle

    Bazen aynı anda birkaç eylemi gerçekleştirmek gerekli hale gelir, örneğin, bir veritabanı tablosundaki değişiklikleri kontrol edin ve diğerinde değişiklikler yapın. Ayrıca, işlemlerden biri (örneğin değişiklikleri kontrol etme) uzun sürerse, sıralı yürütmenin kaynak dengelemesi sağlayamayacağı açıktır.

    Bu tür sorunları çözmek için, programlama çoklu iş parçacığı kullanır - her işlem, tahsis edilmiş miktarda kaynakla ayrı bir iş parçacığına yerleştirilir ve içinde çalışır. Bu yaklaşımla, tüm görevler ayrı ayrı ve bağımsız olarak gerçekleştirilecektir.

    PHP çoklu iş parçacığını desteklemese de, onu taklit etmek için aşağıda tartışılacak olan birkaç yöntem vardır.

    1. Komut dosyasının birden çok kopyasını çalıştırma - işlem başına bir kopya

    //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"] == "make_me_happy") ( make_her_happy(); ) elseif ($_GET["thread"] == "make_me_rich" ) ( find_another_one() ; )

    Bu betiği parametresiz çalıştırdığımızda, gerekli işlevleri başlatan işlem kimlikleriyle ("thread=make_me_happy" ve "thread=make_me_rich") kendisinin iki kopyasını otomatik olarak başlatır.

    Böylece, istenen sonucu elde ederiz - iki işlem aynı anda gerçekleştirilir - ancak bu elbette çok iş parçacıklı değil, aynı anda görevleri gerçekleştirmek için sadece bir koltuk değneğidir.

    2. Path of the Jedi - PCNTL uzantısını kullanma

    PCNTL, süreçlerle tam olarak çalışmanıza izin veren bir uzantıdır. Yönetime ek olarak, mesaj göndermeyi, durumu kontrol etmeyi ve öncelikleri ayarlamayı destekler. PCNTL'yi kullanan önceki komut dosyası şöyle görünür:

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

    Oldukça kafa karıştırıcı görünüyor, satır satır gidelim.

    İlk satırda, mevcut süreci "çatallıyoruz" (çatal - işlemi tüm değişkenlerin değerlerini tutmaktan kopyalamak), paralel olarak çalışan iki işleme (mevcut ve alt) bölüyoruz.

    Şu anda nerede olduğumuzu anlamak için, alt veya üst süreçte, pcntl_fork işlevi alt öğe için 0 ve ebeveyn için işlem kimliği döndürür. Bu nedenle, ikinci satırda $pid'e bakarız, eğer sıfırsa, o zaman alt süreçteyiz - işlevi yürütürüz, aksi takdirde üst süreçteyiz (4. satır), sonra başka bir süreç yaratırız ve görevi aynı şekilde gerçekleştirin.

    Komut dosyası yürütme süreci:

    Böylece, komut dosyası, kopyaları olan ve benzer değerlere sahip aynı değişkenleri içeren 2 alt süreç daha oluşturur. Ve pcntl_fork fonksiyonunun döndürdüğü identifier yardımı ile şu anda hangi streamde bulunduğumuza yönleniyor ve gerekli işlemleri yapıyoruz.



    Geçenlerde pthreads denedim ve hoş bir sürpriz oldu - bu, PHP'ye birkaç gerçek iş parçacığıyla çalışma yeteneği ekleyen bir uzantıdır. Öykünme yok, sihir yok, sahte yok - her şey gerçek.



    Bu konuya bakıyorum. Hızlı bir şekilde tamamlanması gereken bir görev havuzu var. PHP'de bu sorunu çözmek için başka araçlar da var, burada bahsedilmiyor, makale pthreads hakkında.



    pthreads nedir

    Bu kadar! Neredeyse her şey. Aslında, meraklı okuyucuyu üzebilecek bir şey var. Bunların hiçbiri, varsayılan seçeneklerle derlenmiş standart PHP üzerinde çalışmaz. Çoklu okumanın keyfini çıkarmak için PHP'nizde ZTS'nin (Zend Thread Safety) etkinleştirilmiş olması gerekir.

    PHP kurulumu

    Ardından, ZTS ile PHP. ZTS'siz PHP ile karşılaştırıldığında (37.65'e karşı 265.05 saniye) yürütme süresindeki bu kadar büyük bir farkı görmezden gelin, PHP kurulumunu genelleştirmeye çalışmadım. ZTS'siz durumda, örneğin XDebug'u etkinleştirdim.


    Gördüğünüz gibi, 2 iş parçacığı kullanıldığında, program yürütme hızı, doğrusal kod durumundan yaklaşık 1,5 kat daha yüksektir. 4 iplik kullanırken - 3 kez.


    İşlemci 8 çekirdekli olmasına rağmen, 4'ten fazla iş parçacığı kullanıldığında program yürütme süresinin neredeyse değişmediğini fark edebilirsiniz. Görünüşe göre bu, işlemcimin 4 fiziksel çekirdeğe sahip olmasından kaynaklanıyor.Netlik için bir plakayı diyagram şeklinde tasvir ettim.


    Özet

    PHP, pthreads uzantısını kullanarak oldukça şık çoklu kullanım sağlar. Bu, gözle görülür bir performans artışı sağlar.

    PHP geliştiricilerinin nadiren paralellik kullandığı görülüyor. Senkronize kodun basitliğinden bahsetmeyeceğim, tek iş parçacıklı programlama elbette daha basit ve daha nettir, ancak bazen paralelliğin biraz kullanılması gözle görülür bir performans artışı getirebilir.

    Bu yazıda, pthreads uzantısını kullanarak PHP'de çoklu okumanın nasıl sağlanabileceğine bir göz atacağız. Bu, kurulu pthreads v3 uzantısıyla birlikte PHP 7.x'in bir ZTS (Zend Thread Safety) sürümünün kurulu olmasını gerektirir. (Yazma sırasında, PHP 7.1'de, kullanıcıların pthreads deposundaki ana daldan yükleme yapmaları gerekir - üçüncü taraf uzantısına bakın.)

    Küçük bir açıklama: pthreads v2 PHP 5.x içindir ve artık desteklenmemektedir, pthreads v3 PHP 7.x içindir ve aktif olarak geliştirilmektedir.

    Böyle bir ara konuşmadan sonra, hemen işe başlayalım!

    Tek seferlik görevleri işleme

    Bazen tek seferlik görevleri çok iş parçacıklı bir şekilde işlemek istersiniz (örneğin, bazı G/Ç'ye bağlı görevleri yürütmek). Bu gibi durumlarda, yeni bir iş parçacığı oluşturmak ve ayrı bir iş parçacığı üzerinde bazı işlemleri çalıştırmak için Thread sınıfını kullanabilirsiniz.

    Örneğin:

    $task = yeni sınıf Thread'i genişletir ( private $response; public function run() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+)~", $content, $matches); $this->response = $matches; ) ); $task->start() && $task->join(); var_dump($task->response); // string (6) "Google"

    Burada run metodu yeni thread içerisinde yapılacak olan işlemimizdir. Thread::start çağrıldığında, yeni bir thread oluşturulur ve run metodu çağrılır. Daha sonra, ortaya çıkan iş parçacığı yürütmeyi bitirene kadar engelleyecek olan Thread::join öğesini çağırarak ortaya çıkan iş parçacığını ana iş parçacığına geri bağlarız. Bu, biz sonucu ($task->response içinde saklanır) çıktısını almaya çalışmadan önce görevin yürütülmesinin bitmesini sağlar.

    İş parçacığı mantığıyla ilgili ek sorumluluklarla (bir çalıştırma yöntemi tanımlama sorumluluğu dahil) bir sınıfı kirletmek istenmeyebilir. Bu tür sınıfları Threaded sınıfından türeterek izole edebiliriz. Sonra başka bir iş parçacığının içinde çalıştırılabilirler:

    Class Task, Threaded'i genişletir ( public $response; public function someWork() ( $content = file_get_contents("http://google.com"); preg_match("~ (.+) ~", $content, $matches); $ this->response = $eşleşmeler; )) $görev = yeni Görev; $thread = new class($task) Thread'i genişletir ( private $task; public function __construct(Threaded $task) ( $this->task = $task; ) public function run() ( $this->task->someWork( ); ) ); $thread->start() && $thread->join(); var_dump($görev->yanıt);

    Ayrı bir iş parçacığında çalıştırılması gereken herhangi bir sınıf, zorunlu Threaded sınıfından miras alır. Bunun nedeni, farklı iş parçacıkları üzerinde işleme gerçekleştirmek için gerekli yeteneklerin yanı sıra örtük güvenlik ve kullanışlı arabirimler (kaynak senkronizasyonu gibi) sağlamasıdır.

    pthreads uzantısı tarafından sağlanan sınıf hiyerarşisine bir göz atalım:

    Dişli (Traversable, Collectable uygular) Thread Worker Uçucu Havuz

    Thread ve Threaded sınıflarının temellerini zaten öğrendik ve öğrendik, şimdi diğer üçüne (Worker , Volatile ve Pool) bir göz atalım.

    Konu yeniden kullanımı

    Paralelleştirilmesi gereken her görev için yeni bir iş parçacığı başlatmak oldukça pahalıdır. Bunun nedeni, PHP içinde çoklu kullanım elde etmek için "ortak olmayan" mimarinin pthreads içinde uygulanması gerektiğidir. Bu, PHP yorumlayıcısının mevcut örneğinin tüm yürütme bağlamının (her sınıf, arayüz, özellik ve işlev dahil) oluşturulan her iş parçacığı için kopyalanması gerektiği anlamına gelir. Bunun gözle görülür bir performans etkisi olduğundan, bir iş parçacığı her zaman mümkün olduğunda yeniden kullanılmalıdır. İş parçacıkları iki şekilde yeniden kullanılabilir: Worker s ile veya Pool s ile.

    Worker sınıfı, başka bir iş parçacığı içinde eşzamanlı olarak bir dizi görevi gerçekleştirmek için kullanılır. Bu, Worker'ın (yeni bir iş parçacığı oluşturan) yeni bir örneğini oluşturarak ve ardından görevleri o bireysel iş parçacığının yığınına iterek (Worker::stack kullanarak) yapılır.

    İşte küçük bir örnek:

    Class Task, Threaded ( private $value; public function __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Görev: ($this->value) öğesini genişletir. \n"; ) ) $çalışan = yeni Çalışan(); $işçi->başlangıç(); for ($i = 0; $i stack(new Task($i)); ) while ($worker->collect()); $işçi->kapatma();

    Yukarıdaki örnekte, Worker::stack yöntemi aracılığıyla yeni bir $worker nesnesi için yığına 15 görev gönderilir ve ardından, gönderildikleri sırayla işlenirler. Worker::collect yöntemi, yukarıda gösterildiği gibi, görevleri yürütmeyi bitirir bitirmez temizlemek için kullanılır. Bununla birlikte, while döngüsünün içinde, yığındaki tüm görevler tamamlanana ve temizlenene kadar ana iş parçacığını engelleriz - Worker::shutdown çağırmadan önce. Bir çalışanı erken sonlandırmak (yani, hala tamamlanması gereken görevler varken), tüm görevler yürütülmesini tamamlayana kadar ana iş parçacığını engellemeye devam eder, yalnızca görevler çöp olarak toplanmaz (bu da bellek sızıntılarını gerektirir).

    Worker sınıfı, son eklenen görevi kaldırmak için Worker::unstack ve yürütme yığınındaki görev sayısını almak için Worker::getStacked dahil olmak üzere görev yığınıyla ilgili birkaç başka yöntem sağlar. Çalışanın yığını yalnızca tamamlanması gereken görevleri içerir. Yığındaki bir görev tamamlandığında, kaldırılır ve çöp toplama için ayrı bir (dahili) yığına yerleştirilir (Worker::collect yöntemini kullanarak).

    Bir iş parçacığını birçok görev için yeniden kullanmanın başka bir yolu da bir iş parçacığı havuzu kullanmaktır (Havuz sınıfı aracılığıyla). İş parçacığı havuzu, görevlerin çalışmasına izin vermek için bir grup Çalışan kullanır eşzamanlı havuz oluşturulduğunda eşzamanlılık faktörünün (üzerinde çalıştığı havuz iş parçacıklarının sayısı) ayarlandığı .

    Yukarıdaki örneği bir işçi havuzu kullanacak şekilde uyarlayalım:

    Class Task, Threaded ( private $value; public function __construct(int $i) ( $this->value = $i; ) public function run() ( usleep(250000); echo "Görev: ($this->value) öğesini genişletir. \n"; ) ) $havuz = yeni Havuz(4); for ($i = 0; $i send(new Task($i)); ) while ($pool->collect()); $havuz->kapatma();

    Bir işçinin aksine bir havuz kullanırken birkaç dikkate değer fark vardır. İlk olarak, havuzun manuel olarak başlatılmasına gerek yoktur, görevleri kullanılabilir hale gelir gelmez yürütmeye başlar. İkincisi, biz göndermek havuza görevler, değil onları bir yığına koy. Ayrıca, Pool sınıfı Threaded'den miras almaz ve bu nedenle diğer threadlere geçirilemez (Worker'ın aksine).

    İyi bir uygulama olarak, çalışanlar ve havuzlar görevlerini her zaman tamamlar tamamlamaz temizlemeli ve ardından kendilerini manuel olarak sonlandırmalıdır. Thread sınıfı ile oluşturulan threadler de ana thread'e eklenmelidir.

    pthreads ve (değil) değiştirilebilirlik

    Son değineceğimiz sınıf, pthreads v3'e yeni bir ekleme olan Volatile. Değişmezlik kavramı, pthread'lerde önemli bir kavram haline geldi, çünkü onsuz performans önemli ölçüde düşüyor. Bu nedenle, varsayılan olarak, kendileri Threaded nesneler olan Threaded sınıflarının özellikleri artık değişmezdir ve bu nedenle, orijinal olarak atandıktan sonra üzerine yazılamaz. Bu tür özellikler için açık değişkenlik şu anda tercih edilmektedir ve yine de yeni Volatile sınıfıyla elde edilebilir.

    Yeni değişmezlik kısıtlamalarını gösteren bir örneğe bakalım:

    Class Task, Threaded // bir Threaded sınıfını genişletir ( public function __construct() ( $this->data = new Threaded(); // $this->data, Threaded sınıfının bir Threaded özelliği olduğundan, üzerine yazılamaz)) $task = new class(new Task()) Thread'i genişletir ( // Threaded class'ı genişletir, çünkü Thread Threaded public function __construct($tm) ( $this->threadedMember = $tm; var_dump($this->threadedMember->) data); // object(Threaded)#3 (0) () $this->threadedMember = new StdClass(); // özellik bir Threaded sınıfının Threaded üyesi olduğundan geçersiz ) );

    Öte yandan, Uçucu sınıfların Dişli özellikleri değişkendir:

    Sınıf Görevi Uçucu'yu genişletir ( public function __construct() ( $this->data = new Threaded(); $this->data = new StdClass(); // volatile bir sınıfta olduğumuz için geçerlidir) $task = new class(new Task()) Thread'i genişletir ( public function __construct($vm) ( $this->volatileMember = $vm; var_dump($this->volatileMember->data); // object(stdClass)#4 (0) () // hala geçersiz, çünkü Volatile Threaded öğesini genişletiyor, bu nedenle özellik hala Threaded sınıfının bir Threaded üyesidir $this->volatileMember = new StdClass(); ) );

    Volatile sınıfının, Threaded özelliklerini (ayrıca unset() ) değiştirme yeteneği sağlamak için Threaded üst sınıfı tarafından uygulanan değişmezliği geçersiz kıldığını görüyoruz.

    Değişebilirlik ve Uçucu sınıf - diziler konusunu ele almak için tartışılacak bir konu daha var. pthreads'de diziler, Threaded sınıfının bir özelliğine atandığında otomatik olarak Volatile nesnelere dönüştürülür. Bunun nedeni, birden çok PHP bağlamından bir diziyi değiştirmenin güvenli olmamasıdır.

    Bazı şeyleri daha iyi anlamak için örneğe tekrar bakalım:

    $dizi = ; $görev = yeni sınıf($dizi) Konuyu genişletir ( private $data; public function __construct(array $array) ( $this->data = $array; ) public function run() ( $this->data = 4; $ this->data = 5; print_r($this->data); ) ); $görev->başlangıç() && $görev->birleştir(); /* Çıktı: Uçucu Nesne ( => 1 => 2 => 3 => 4 => 5) */

    Volatile nesnelerinin, alt küme operatörü () gibi (yukarıda gösterildiği gibi) dizi işlemlerini destekledikleri için diziler gibi ele alınabileceğini görüyoruz. Ancak, Volatile sınıfları array_pop ve array_shift gibi temel dizi işlevlerini desteklemez. Bunun yerine, Threaded sınıfı bize yerleşik yöntemlerle benzer işlemler sağlar.

    Demo olarak:

    $veri = yeni sınıf Uçucu'yu genişletir ( public $a = 1; public $b = 2; public $c = 3; ); var_dump($veri); var_dump($veri->pop()); var_dump($veri->shift()); var_dump($veri); /* Çıktı: nesne( [e-posta korumalı])#1 (3) ( ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(3) ) int(3) int(1) nesne ( [e-posta korumalı])#1 (1) ( ["b"]=> int(2) ) */

    Desteklenen diğer işlemler arasında Threaded::chunk ve Threaded::merge bulunur.

    senkronizasyon

    Bu makalenin son bölümünde, pthreads'de senkronizasyona bakacağız. Senkronizasyon, paylaşılan kaynaklara erişimi kontrol etmenizi sağlayan bir yöntemdir.

    Örneğin, basit bir sayaç uygulayalım:

    $counter = yeni sınıf Thread'i genişletir ( public $i = 0; public function run() ( for ($i = 0; $i i; ) ) ); $sayaç->başlat(); for ($i = 0; $i i; ) $counter->join(); var_dump($counter->i); // 10'dan 20'ye kadar bir sayı yazdırır

    Senkronizasyon kullanılmadan çıktı deterministik değildir. Birden çok iş parçacığı, kontrollü erişim olmadan aynı değişkene yazar, bu da güncellemelerin kaybolacağı anlamına gelir.

    Bunu düzeltelim, böylece bir senkronizasyon ekleyerek 20'nin doğru çıktısını elde edelim:

    $counter = yeni sınıf Thread'i genişletir ( public $i = 0; public function run() ( $this->synchroized(function() ( for ($i = 0; $i i; ) )); ) ); $sayaç->başlat(); $counter->synchronized(function ($counter) ( for ($i = 0; $i i; ) ), $counter); $counter->join(); var_dump($counter->i); // int(20)

    Senkronize kod blokları, Threaded::wait ve Threaded::notify (veya Threaded::notifyAll) yöntemlerini kullanarak da birbirleriyle iletişim kurabilir.

    İşte iki senkronize while döngüsünde alternatif bir artış:

    $counter = yeni sınıf Thread'i genişletir ( public $cond = 1; public function run() ( $this->synchronized(function()) ( for ($i = 0; $i notify(); if ($this->cond) === 1) ( $bu->koşul = 2; $bu->bekle(); ) )); ) ); $sayaç->başlat(); $counter->synchronized(function ($counter) ( if ($counter->cond !== 2) ( $counter->wait(); // önce diğerinin başlamasını bekleyin ) for ($i = 10; $i notify(); if ($counter->cond === 2) ( $counter->cond = 1; $counter->wait(); ) ) ), $counter); $counter->join(); /* Çıktı: 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) */

    Threaded::wait çağrısının etrafına yerleştirilmiş ek koşulları fark edebilirsiniz. Bu koşullar, bir bildirim aldığında ve belirtilen koşul doğru olduğunda, senkronize edilmiş bir geri aramanın devam etmesine izin verdiği için önemlidir. Bu önemlidir çünkü bildirimler Threaded::notify çağrıldığında başka yerlerden gelebilir. Bu nedenle, Threaded::wait yöntemine yapılan çağrılar koşullara sarılmamışsa, yürütürdük yanlış uyandırma çağrıları, bu da öngörülemeyen kod davranışına yol açacaktır.

    Çözüm

    pthreads paketindeki beş sınıfa (Threaded , Thread , Worker , Volatile ve Pool) ve her sınıfın nasıl kullanıldığına baktık. Ayrıca, pthreads'deki yeni değişmezlik kavramına bir göz attık, desteklenen senkronizasyon özelliklerine kısa bir genel bakış yaptık. Bu temel bilgiler yerine getirildikten sonra, gerçek dünya durumlarında pthreads'in nasıl kullanılacağına bakmaya başlayabiliriz! Bu bir sonraki yazımızın konusu olacak.

    Bir sonraki gönderinin çevirisiyle ilgileniyorsanız, bana bildirin: sosyal medyada yorum yapın. ağlar, oy verin ve gönderiyi meslektaşlarınız ve arkadaşlarınızla paylaşın.

    Geçenlerde pthreads denedim ve hoş bir sürpriz oldu - bu, PHP'ye birkaç gerçek iş parçacığıyla çalışma yeteneği ekleyen bir uzantıdır. Öykünme yok, sihir yok, sahte yok - her şey gerçek.



    Bu konuya bakıyorum. Hızlı bir şekilde tamamlanması gereken bir görev havuzu var. PHP'de bu sorunu çözmek için başka araçlar da var, burada bahsedilmiyor, makale pthreads hakkında.



    pthreads nedir

    Bu kadar! Neredeyse her şey. Aslında, meraklı okuyucuyu üzebilecek bir şey var. Bunların hiçbiri, varsayılan seçeneklerle derlenmiş standart PHP üzerinde çalışmaz. Çoklu okumanın keyfini çıkarmak için PHP'nizde ZTS'nin (Zend Thread Safety) etkinleştirilmiş olması gerekir.

    PHP kurulumu

    Ardından, ZTS ile PHP. ZTS'siz PHP ile karşılaştırıldığında (37.65'e karşı 265.05 saniye) yürütme süresindeki bu kadar büyük bir farkı görmezden gelin, PHP kurulumunu genelleştirmeye çalışmadım. ZTS'siz durumda, örneğin XDebug'u etkinleştirdim.


    Gördüğünüz gibi, 2 iş parçacığı kullanıldığında, program yürütme hızı, doğrusal kod durumundan yaklaşık 1,5 kat daha yüksektir. 4 iplik kullanırken - 3 kez.


    İşlemci 8 çekirdekli olmasına rağmen, 4'ten fazla iş parçacığı kullanıldığında program yürütme süresinin neredeyse değişmediğini fark edebilirsiniz. Görünüşe göre bu, işlemcimin 4 fiziksel çekirdeğe sahip olmasından kaynaklanıyor.Netlik için bir plakayı diyagram şeklinde tasvir ettim.


    Özet

    PHP, pthreads uzantısını kullanarak oldukça şık çoklu kullanım sağlar. Bu, gözle görülür bir performans artışı sağlar.

    Etiketler: Etiketler ekle