PHP'de iş parçacığı var mı?


130

Konu adı verilen bu PECL paketini buldum , ancak henüz bir yayın yok. Ve PHP web sitesinde hiçbir şey çıkmıyor.


pcntl_fork()Apache'den çağrıldığında bu ( ) işlevinin çalışıp çalışmayacağını bilen var mı?
Josh K

Bu inanılmaz derecede eski, ancak aslında php'de iş parçacığı sağlayan bir cevabım var (bağlantılar için aşağıya bakın).
Alec Gorge

Fork'u bir sunucu ortamından çağırmamayı tavsiye ederler. Onları suçlamıyorum. Bununla birlikte, pcntl_fork, PHP'nin iş parçacığı oluşturmak için en iyi çözüm gibi görünüyor.
just_wes

Evet, bir apache2 php sürecini çatallamanıza gerek yok.
andho

2
Pthreads kullanın cazibe gibi çalışır
Baba

Yanıtlar:


40

Bildiğim hiçbir şey yok. Bir sonraki en iyi şey, bir komut dosyasının diğerini CLI aracılığıyla yürütmesi olacaktır, ancak bu biraz temeldir. Ne yapmaya çalıştığınıza ve ne kadar karmaşık olduğuna bağlı olarak, bu bir seçenek olabilir veya olmayabilir.


1
Bende böyle düşünmüştüm. Php.net'te hayır diyen ve hiçbir şey söyleyen bir sürü eski ilan gördüm, bu yüzden düşüncem buydu. Onayladığınız için teşekkürler.
Thomas Owens

2
Evet, bu PECL paketi bir çeşit alay - ben de onunla karşılaştım ama hiçbir şey çıkmadı.
Wilco

180

Pthreads uzantısı için PHP kılavuzundan :

pthreads, PHP'de kullanıcı alanlı çoklu iş parçacığı oluşturmaya izin veren Nesne Yönelimli bir API'dir. Web veya Konsolu hedefleyen çok iş parçacıklı uygulamalar oluşturmak için ihtiyacınız olan tüm araçları içerir. PHP uygulamaları Threads, Workers ve Stackables oluşturabilir, okuyabilir, yazabilir, çalıştırabilir ve senkronize edebilir.

Bu kulağa inanılmaz gelse de, tamamen doğru. Bugün, PHP, denemek isteyenler için çoklu iş parçacığı oluşturabilir.

PHP4'ün ilk sürümü, 22 Mayıs 2000, PHP, çok iş parçacıklı SAPI (Sunucu API) ortamlarında kendi yorumlayıcısının birden çok örneğini ayrı iş parçacıkları içinde yürütmenin bir yolu olan iş parçacığı güvenli bir mimariyle birlikte gönderildi. Son 13 yılda, bu mimarinin tasarımı korunmuş ve geliştirilmiştir: O zamandan beri dünyanın en büyük web sitelerinde üretimde kullanılmaktadır.

Kullanıcı alanında iş parçacığı oluşturmak PHP ekibi için hiçbir zaman bir sorun olmadı ve bugün de öyle. PHP'nin iş yaptığı dünyada, zaten tanımlanmış bir ölçeklendirme yöntemi olduğunu anlamalısınız - donanım ekleyin. Uzun yıllar boyunca PHP var oldu, donanım daha ucuz ve ucuz hale geldi ve bu nedenle bu, PHP ekibi için giderek daha az endişe verici hale geldi. Giderek ucuzlarken, çok daha güçlü hale geldi; Günümüzde, cep telefonlarımız ve tabletlerimiz çift ve dört çekirdekli mimarilere ve buna uygun bol miktarda RAM'e sahiptir, masaüstü bilgisayarlarımız ve sunucularımızda genellikle 8 veya 16 çekirdek, 16 ve 32 gigabayt RAM vardır, ancak her zaman iki çekirdekli olmayabiliriz. bütçe dahilinde ve iki masaüstüne sahip olmak çoğumuz için nadiren yararlıdır.

Ek olarak, PHP programcı olmayanlar için yazılmıştır, birçok hobicinin anadilidir. PHP'nin bu kadar kolay benimsenmesinin nedeni, öğrenmesi ve yazması kolay bir dil olmasıdır. PHP'nin bugün bu kadar güvenilir olmasının nedeni, tasarımına giren çok fazla çalışma ve PHP grubu tarafından alınan her bir karardır. Güvenilirliği ve mükemmelliği, bunca yıldan sonra onu spot ışıkta tutar; rakiplerinin zamana veya baskıya düştüğü yer.

Çok iş parçacıklı programlama, en tutarlı ve güvenilir API ile bile çoğu için kolay değildir, üzerinde düşünülmesi gereken farklı şeyler ve birçok yanlış anlama vardır. PHP grubu, kullanıcının çoklu iş parçacığı bağlantısının temel bir özellik olmasını istemez, hiçbir zaman ciddi bir ilgi gösterilmemiştir - ve haklı olarak öyle. PHP herkes için karmaşık olmamalıdır.

Her şey düşünüldüğünde, PHP'nin üretime hazır ve test edilmiş özelliklerinden yararlanmasına izin vermenin, sahip olduklarımızdan en iyi şekilde yararlanma yoluna izin vermenin, daha fazlasını eklemek her zaman bir seçenek olmadığında ve pek çok şey için olmasına izin vermenin hala faydaları vardır. göreve asla gerçekten ihtiyaç duyulmaz.

pthreads, onu keşfetmek isteyenler için, bir kullanıcının çok iş parçacıklı PHP uygulamalarına izin veren bir API elde eder. API'si devam eden bir çalışmadır ve bir beta kararlılık ve bütünlük seviyesi belirlemiştir.

PHP'nin kullandığı bazı kitaplıkların iş parçacığı açısından güvenli olmadığı yaygın bir bilgidir, programcı için pthreads'ın bunu değiştiremeyeceği ve denemeye çalışmayacağı açık olmalıdır. Ancak, iş parçacığı açısından güvenli olan herhangi bir kitaplık, yorumlayıcının diğer iş parçacığı güvenli kurulumunda olduğu gibi kullanılabilir.

pthreads, Posix Threads kullanır (Windows'ta bile), programcının yarattığı gerçek yürütme iş parçacıklarıdır, ancak bu evrelerin yararlı olması için PHP'nin farkında olmaları gerekir - kullanıcı kodunu çalıştırabilir, değişkenleri paylaşabilir ve yararlı bir iletişim aracına izin verebilir. (senkronizasyon). Böylece her iş parçacığı, yorumlayıcının bir örneğiyle oluşturulur, ancak tasarım gereği, yorumlayıcısı, yorumlayıcının diğer tüm örneklerinden izole edilmiştir - tıpkı çok iş parçacıklı Sunucu API ortamları gibi. pthreads, boşluğu aklı başında ve güvenli bir şekilde kapatmaya çalışır. C'deki iş parçacığı programcısının endişelerinin çoğu, pthreads programcısı için orada değildir, tasarım gereği, pthreads okunduğunda kopyalanır ve yazılırken kopyalanır (RAM ucuzdur), bu nedenle iki örnek aynı fiziksel verileri hiçbir zaman değiştiremez , ancak her ikisi de başka bir iş parçacığındaki verileri etkileyebilir.

Neden yazarken kopyala ve oku:

public function run() {
    ...
    (1) $this->data = $data;
    ...
    (2) $this->other = someOperation($this->data);
    ...
}

(3) echo preg_match($pattern, $replace, $thread->data);

(1) pthreads nesnesi veri deposunda bir okuma ve yazma kilidi tutulurken, veriler bellekteki orijinal konumundan nesne deposuna kopyalanır. pthreads, değişkenin refcount'unu ayarlamaz, Zend, kendisine başka referans yoksa orijinal veriyi serbest bırakabilir.

(2) someOperation argümanı nesne deposuna atıfta bulunur, kendisinin (1) sonucunun bir kopyası olan depolanan orijinal veriler, motor için tekrar bir zval konteynerine kopyalanır, bu durumda bir okuma kilidi tutulur. nesne deposu, kilit serbest bırakılır ve motor işlevi çalıştırabilir. Zval oluşturulduğunda, 0'lık bir refcount değerine sahiptir ve motorun işlem tamamlandığında kopyayı serbest bırakmasını sağlar, çünkü başka hiçbir referans yoktur.

(3) preg_match için son argüman veri deposuna referans verir, bir okuma kilidi elde edilir, (1) 'deki veri seti yine 0 refcount ile bir zval'e kopyalanır. Kilit serbest bırakılır, preg_match çağrısı çalışır verilerin bir kopyası, yani orijinal verilerin bir kopyası.

Bilinecek şeyler:

  • Nesne deposunun verilerin depolandığı, iş parçacığı güvenli olan karma tablosu
    , Zend tarafından PHP ile birlikte gönderilen TsHashTable'a dayanmaktadır.

  • Nesne deposu bir okuma ve yazma kilidine sahiptir, TsHashTable için ek bir erişim kilidi sağlanır, öyle ki gerekirse (ve bunu yapar, var_dump / print_r, PHP motoru onlara başvurmak istediği için özelliklere doğrudan erişim) pthreads TsHashTable'ı işleyebilir tanımlı API'nin dışında.

  • Kilitler yalnızca kopyalama işlemleri meydana gelirken, kopyalar yapıldığında kilitler mantıklı bir sırada açılırken tutulur.

Bu şu anlama gelir:

  • Bir yazma gerçekleştiğinde, yalnızca bir okuma ve yazma kilidi değil, aynı zamanda ek bir erişim kilidi de tutulur. Tablonun kendisi kilitlenmiştir, başka bir bağlamın onu kilitlemesi, okuyabilmesi, yazması veya etkilemesi mümkün değildir.

  • Bir okuma gerçekleştiğinde, sadece okuma kilidi tutulmaz, aynı zamanda ek erişim kilidi de tutulur, yine masa kilitlenir.

İki bağlam, nesne deposundan aynı verilere fiziksel olarak veya aynı anda erişemez, ancak herhangi bir bağlamda bir referansla yapılan yazılar, bir referansla herhangi bir bağlamda okunan verileri etkileyecektir.

Bu mimari hiçbir şey paylaşılmaz ve var olmanın tek yolu bir arada var olmaktır. Biraz anlayışlı olanlar bunu görecek, burada çok fazla kopyalama var ve bunun iyi bir şey olup olmadığını merak edecekler. Dinamik bir çalışma süresi içinde oldukça fazla kopyalama devam eder, bu dinamik bir dilin dinamikleridir. pthreads nesne düzeyinde uygulanır, çünkü bir nesne üzerinde iyi bir kontrol elde edilebilir, ancak yöntemler - programcının yürüttüğü kod - başka bir bağlama sahiptir, kilitlenmeden ve kopyalamadan - yerel yöntem kapsamı. Bir pthreads nesnesi durumunda nesne kapsamı, bağlamlar arasında veri paylaşmanın bir yolu olarak görülmelidir, bu amaçtır. Bunu göz önünde bulundurarak, gerekmedikçe nesne deposunu kilitlemekten kaçınmak için teknikler uygulayabilirsiniz.

PHP için mevcut kitaplıkların ve uzantıların çoğu 3. tarafların etrafındaki ince sarmalayıcılardır, PHP çekirdek işlevselliği bir dereceye kadar aynı şeydir. pthreads, Posix Threads etrafında ince bir paketleyici değildir; Posix Threads tabanlı bir iş parçacığı API'sidir. PHP'de Threads uygulamasının kullanıcılarının anlamadığı veya kullanamayacağı bir anlamı yoktur. Muteksin ne olduğu veya ne yaptığı hakkında bilgisi olmayan bir kişinin hem beceri hem de kaynaklar açısından sahip oldukları her şeyden yararlanamaması için hiçbir neden yoktur. Bir nesne bir nesne gibi işlev görür, ancak aksi takdirde iki bağlamın çarpışacağı her yerde, pthreads kararlılık ve güvenlik sağlar.

Java'da çalışan herkes, bir pthreads nesnesi ile java'da iş parçacığı arasındaki benzerlikleri görecek, aynı kişiler şüphesiz ConcurrentModificationException adında bir hata görmeyecekler - çünkü iki iş parçacığı aynı fiziksel verileri yazarsa java çalışma zamanı tarafından ortaya çıkan bir hata gibi. eşzamanlı. Neden var olduğunu anlıyorum, ancak bu kadar ucuz kaynaklarla, çalışma zamanının eşzamanlılığı tam ve tek zamanda kullanıcı için güvenliğin elde edilebileceği ve seçtiği anda tespit edebilmesi beni şaşırtıyor. yürütmeyi ve verilere erişimi yönetmek yerine çalışma zamanında muhtemelen ölümcül bir hata atmak.

Pthreads tarafından bu tür aptalca hatalar yayılmayacaktır, API, iş parçacığını olabildiğince istikrarlı ve uyumlu hale getirmek için yazılmıştır, inanıyorum.

Çoklu iş parçacığı, yeni bir veritabanı kullanmak gibi değildir, kılavuzdaki her kelimeye ve pthreads ile birlikte gönderilen örneklere çok dikkat edilmelidir.

Son olarak, PHP kılavuzundan:

pthreads oldukça iyi sonuçlara sahip bir deneydi ve öyle. Sınırlamaları veya özelliklerinden herhangi biri herhangi bir zamanda değişebilir; deney yapmanın doğası budur. Genellikle uygulama tarafından empoze edilen sınırlamalar iyi bir nedenle mevcuttur; pthreads'ın amacı, PHP'de herhangi bir düzeyde çoklu görev için kullanılabilir bir çözüm sağlamaktır. Pthreads'ın yürüttüğü ortamda, kararlı bir ortam sağlamak için bazı kısıtlamalar ve sınırlamalar gereklidir.


14
Kesin saçmalık.
Joe Watkins

7
@GeoC. Burada amacınızın ne olduğundan bile emin değilim, bu sadece bir sürü anlamsız söz ve siz hiçbir nedenleri , mantıksal veya aksi takdirde (Gerçekten sonrası herhangi göremiyorum hangi) herhangi bir argüman kabul etmiyorsanız neden olarak .
Jimbo

13
@Tudor Ne hakkında konuştuğunu gerçekten bildiğini sanmıyorum, bu yüzden seni görmezden geldiğim için mutluyum.
Joe Watkins

4
@Tudor - birçok bilim insanı kendi dallarında yeni bir şeyin veya yararlı bir şeyin "amacını" görmedi. Tarih göstermiştir ki, çoğu zaman sizin gibi insanlar basitçe yanılıyor, bu bir gerçek. Tıpkı burada yazdığınız her şeyin daha iyi bir kelime olmadığı için dışkı olduğu gibi. Olumlu olan her şeyi göz önünde bulundurarak, hakkında hiçbir şey bilmediğiniz konularda yer almamanızı şiddetle tavsiye ederim (bu bir tanesidir).
NB

12
Komik şey. Joe Watkins, pthreads yazarıdır ve hala Tudor onun yanıldığını kanıtlamaya çalışır.
Hristo Valkanov

48

Wilco'nun önerdiği şeye bir örnek:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);

Temel olarak bu, PHP betiğini komut satırında çalıştırır, ancak hemen PID'yi döndürür ve ardından arka planda çalışır. (Echo $!, PID dışında başka hiçbir şeyin döndürülmemesini sağlar.) Bu, isterseniz PHP betiğinizin devam etmesine veya çıkmasına izin verir. Bunu kullandığımda, kullanıcıyı başka bir sayfaya yönlendirdim, burada her 5 ila 60 saniyede bir AJAX çağrısı raporun hala çalışıp çalışmadığını kontrol etmek için yapılıyor. (Gen_id ve bunun ilişkili olduğu kullanıcıyı depolamak için bir tablom var.) Kontrol komut dosyası aşağıdakileri çalıştırır:

exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
     // less than 2 rows in the ps, therefore report is complete
}

Burada bu teknikle ilgili kısa bir gönderi var: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/


küçük bir problemim var, arka plan işleminin durumunu nasıl kontrol edersiniz? beni aydınlatabilir misin
daha

25

Kısacası: evet, php'de çoklu okuma var ama bunun yerine çoklu işlemeyi kullanmalısınız.

Backgroud bilgisi: iş parçacıkları ve süreçler

İş parçacıkları ve süreçlerin ayrımı konusunda her zaman biraz kafa karışıklığı vardır, bu yüzden ikisini de kısaca açıklayacağım:

  • İş parçacığı , CPU'nun işleyeceği bir komut dizisidir. İçerdiği tek veri bir program sayacıdır. Her CPU çekirdeği bir seferde yalnızca bir iş parçacığı işleyecektir, ancak zamanlama yoluyla farklı olanların yürütülmesi arasında geçiş yapabilir.
  • Bir işlem paylaşılan kaynakların kümesidir. Bu, belleğin, değişkenlerin, nesne örneklerinin, dosya tutamaçlarının, mutekslerin, veritabanı bağlantılarının vb. Bir bölümünden oluştuğu anlamına gelir. Her işlem ayrıca bir veya daha fazla iş parçacığı içerir. Aynı sürecin tüm iş parçacıkları kaynaklarını paylaşır, bu nedenle bir değişkeni başka bir iş parçacığında oluşturduğunuz bir iş parçacığında kullanabilirsiniz. Bu iş parçacıkları iki farklı sürecin parçasıysa, birbirlerinin kaynaklarına doğrudan erişemezler. Bu durumda , örneğin borular, dosyalar, soketler aracılığıyla süreçler arası iletişime ihtiyacınız vardır ...

Çoklu İşlem

Php ile yeni süreçler (ayrıca yeni bir iş parçacığı içeren) oluşturarak paralel hesaplama elde edebilirsiniz. İş parçacıklarınız fazla iletişim veya senkronizasyona ihtiyaç duymuyorsa, bu sizin seçiminizdir çünkü süreçler izole edilmiştir ve birbirlerinin işlerine müdahale edemezler. Biri çökse bile, bu diğerlerini ilgilendirmez. Çok fazla iletişime ihtiyacınız varsa, "multithreading" bölümünde okumaya devam etmelisiniz veya - ne yazık ki - başka bir programlama dili kullanmayı düşünmelisiniz, çünkü süreçler arası iletişim ve senkronizasyon çok fazla ten rengi ortaya çıkarır.

Php'de yeni bir süreç yaratmanın iki yolu vardır:

Bırakın işletim sistemi sizin için yapsın : işletim sisteminize yeni bir işlem oluşturmasını ve içinde yeni (veya aynı) bir php betiği çalıştırmasını söyleyebilirsiniz.

  • için linux aşağıdakileri kullanabilir veya düşünebiliriz Darryl Hein cevabı :

    $cmd = 'nice php script.php 2>&1 & echo $!';
    pclose(popen($cmd, 'r'));
  • için pencereleri Eğer bunu kullanabilir:

    $cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
    pclose(popen($cmd, 'r'));

kendiniz bir çatal ile yapın : php ayrıca pcntl_fork () işlevi aracılığıyla çatal kullanma olanağı sağlar . Bunun nasıl yapılacağına dair iyi bir öğretici burada bulunabilir, ancak çatal insanlığa ve özellikle oop'a karşı bir suç olduğu için kullanmamanızı şiddetle tavsiye ederim .

Çok iş parçacığı

Çoklu iş parçacığı ile tüm iş parçacıklarınız kaynaklarını paylaşır, böylece çok fazla ek yük olmadan aralarında kolayca iletişim kurabilir ve bunları senkronize edebilirsiniz. Öte yandan, yarış koşullarının ve kilitlenmelerin üretilmesi kolay ancak hata ayıklaması çok zor olduğu için ne yaptığınızı bilmeniz gerekir.

Standart php herhangi bir çoklu okuma sağlamaz ama aslında bunu yapan (deneysel) bir uzantı vardır - pthreads . API belgeleri onu php.net'e bile dönüştürdü . Bununla beraber gerçek programlama dillerinde yapabildiğiniz gibi :-) şunun gibi şeyler yapabilirsiniz :

class MyThread extends Thread {
    public function run(){
        //do something time consuming
    }
}

$t = new MyThread();
if($t->start()){
    while($t->isRunning()){
        echo ".";
        usleep(100);
    }
    $t->join();
}

Linux için tam burada stackoverflow'da bir kurulum kılavuzu vardır .

Pencereler için şimdi bir tane var:

  • Öncelikle php'nin iş parçacığı güvenli sürümüne ihtiyacınız var.
  • Hem pthreads hem de php uzantısının önceden derlenmiş sürümlerine ihtiyacınız var. Buradan indirilebilirler . Php sürümünüzle uyumlu olan sürümü indirdiğinizden emin olun.
  • Php_pthreads.dll dosyasını (indirdiğiniz zip dosyasından) php uzantı klasörünüze ([phpDirectory] / ext) kopyalayın.
  • PthreadVC2.dll dosyasını [phpDirectory] içine (kök klasör - uzantı klasörü değil) kopyalayın.
  • [PhpDirectory] /php.ini dosyasını düzenleyin ve aşağıdaki satırı ekleyin

    extension=php_pthreads.dll
  • Biraz uyku veya yorumun olduğu yerde yukarıdaki komut dosyasıyla test edin.

Ve şimdi büyük AMA : Bu gerçekten işe yarasa da, php başlangıçta çoklu okuma için yapılmadı. Php'nin iş parçacığı açısından güvenli bir sürümü var ve v5.4'ten itibaren neredeyse hatasız görünüyor, ancak çok iş parçacıklı bir ortamda php kullanmak hala php kılavuzunda önerilmiyor (ama belki de kılavuzlarını henüz). Çok daha büyük bir sorun, birçok yaygın uzantının iş parçacığı açısından güvenli olmaması olabilir . Yani bu php uzantısıyla iş parçacıkları elde edebilirsiniz, ancak bağlı olduğunuz işlevler hala iş parçacığı açısından güvenli değildir, bu nedenle muhtemelen yarış koşulları, kilitlenmeler ve benzeri kodlarda kendiniz yazmadığınızla karşılaşacaksınız ...


5
Bu korkunç derecede yanlış, atıfta bulunduğunuz makale 2008 yılına ait. PHP, özünde iş parçacığı güvenli olmasaydı, SAPI modüllerini iş parçacığı oluşturmazdı.
Joe Watkins

1
@Joe: Pekala, çekirdekte değiştirdim iş parçacığı güvenli ama birçok uzantı değil.
Francois Bourgeois

1
Çok mu? Sanırım çok az bulursunuz, belgeleri buldunuz ancak düzgün okuyamadınız: Not: * ile işaretlenenler iş parçacığı güvenli kitaplıklar değildir ve PHP ile çoklu sistemde sunucu modülü olarak kullanılmamalıdır. iş parçacıklı Windows web sunucuları (IIS, Netscape). Bu henüz Unix ortamlarında önemli değil.
Joe Watkins

6
PHP çok iş parçacığı güvenlidir ve uzun yıllardır olmuştur, bazı dış kitaplıklar ve birkaç paketlenmiş kitap değildir, ancak iyi belgelenmiştir ve yine de oldukça açıktır. pthreads, çok evreli bir sapi'de zend tarafından oluşturulan evreler kadar güvenli iş parçacıkları oluşturur, bunu biliyorum, çünkü tek başıma pthreads yazdım. PHP tarafından sunulan her API'yi sunucu API'leri gibi kullanır, tamamen kararlı olduğunu söylemiyorum, ancak çizdiğiniz resim tamamen yanlış ve çok az bilgilendirilmiş.
Joe Watkins

@Joe: Kılavuz, bunun Unix ortamları için önemli olmadığını söylediğinde, bunlar Unix sistem apache'nin birden çok işlem kullandığından ve Windows'ta iş parçacığı kullandığından bahsediyorlar. Yani temelde "eğer zaten iş parçacığı kullanmıyorsanız, iş parçacığı güvenli olmayan uzantılar konusunda endişelenmenize gerek yok" diyorlar. Pthreads ile thread kullandığımızda, bu tabii ki Unix ortamlarında da önemli.
Francois Bourgeois

17

Konuya benzer bir şey elde etmek için pcntl_fork () kullanabilirsiniz . Teknik olarak ayrı süreçlerdir, bu nedenle ikisi arasındaki iletişim evreler ile o kadar basit değildir ve PHP apache tarafından çağrılırsa çalışmayacağına inanıyorum.


4
Oldukça büyük bir veri içe aktarma görevini paralelleştirmek için başarıyla pcntl_fork kullanıyorum. Harika çalışıyor ve yaklaşık bir saat içinde çalıştırdım. Biraz öğrenme eğrisi var, ancak neler olduğunu anladığınızda oldukça basit.
Frank Farmer

Frank, bu CLI php veya apache PHP ile mi?
Artem Russakovskii

@Artem: Ben de bilmek isterim.
Josh K

5
@Frank Farmer bizimle dalga geçiyor ... tıpkı PECL paketi gibi.
Roger

1
CLI ile pcntl_fork kullanıyordum. Apache'de hiç denemedim; bu riskli görünüyor. CLI'da bile bazı beklenmedik sorunlar vardı. Bir çocuk bir veritabanı tutamacını kapattığında (işini bitirdiği için) kardeşler için de bağlantıyı kapattığı bir sorun yaşıyor gibiydim. Çocuklar ebeveynin kopyaları olduğu için tuhaflığa hazırlanın. O zamandan beri kodumu exec () aracılığıyla yeni, tamamen ayrı süreçler oluşturmak için yeniden tasarladım - bu şekilde daha temiz.
Frank Farmer


7

pcntl_fork()aradığınız şeydir, ancak süreci çatallanma değil iş parçacığı. Böylece veri alışverişi problemi yaşarsınız. bunları çözmek için phps semafor işlevlerini kullanabilirsiniz ( http://www.php.net/manual/de/ref.sem.php ) kullanabilirsiniz mesaj kuyrukları başlangıç ​​için paylaşılan bellek bölümlerinden biraz daha kolay olabilir.

Her neyse, bir web sayfasının kaynak yoğun bloklarını (muhtemelen harici isteklerle) paralel olarak yükleyen bir web çerçevesinde kullandığım bir strateji: Beklediğim verileri bilmek için bir iş kuyruğu yapıyorum ve sonra çatallanıyorum her işlem için iş dışı. bittikten sonra verilerini apc önbelleğinde, ana sürecin erişebileceği benzersiz bir anahtar altında saklarlar. her veri orada olduğunda devam eder. basitusleep()Beklemek için çünkü apache'de süreçler arası iletişim mümkün değil (çocuklar ebeveynleriyle olan bağlarını kaybedecek ve zombi olacaklar ...). bu yüzden bu beni son şeye getiriyor: her çocuğu kendi kendine öldürmek önemlidir! süreçleri çatallayan ancak verileri tutan sınıflar da var, onları incelemedim ama zend framework'te bir tane var ve genellikle yavaş ama güvenilir kodlar yapıyorlar. burada bulabilirsiniz: http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html shm segmentlerini kullandıklarını düşünüyorum! son olarak ama en az değil, bu zend web sitesinde bir hata var, örnekte küçük bir hata var.

while ($process1->isRunning() && $process2->isRunning()) {
    sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
    sleep(1);
}



5

İki yıldan fazla bir süredir bir üretim ortamında kusursuz bir şekilde çalışan bir PHP iş parçacığı sınıfım var.

DÜZENLEME: Bu artık bir besteci kitaplığı olarak ve MVC çerçevem ​​olan Hazaar MVC'nin bir parçası olarak mevcut.

Bakınız: https://git.hazaarlabs.com/hazaar/hazaar-thread


Ya, örneğinizi takip ederek, file.php'deki program, örneğin, diyelim ki, 10k web sitesinin uris listesinin varlığını doğruluyorsa ve sonucu bir CSV dosyasına kaydetmesi gerekiyorsa ... Bu dosya yazımı bir sorun?
Roger

Alt işlem, web sunucusu / ana komut dosyasıyla aynı kullanıcı olarak çalışacaktır. Dolayısıyla, dosyaları yazarken, normalde yaptığınız gibi izinlerle ilgili aynı hususlara sahip olacaksınız. Dosya yazarken sorun yaşıyorsanız, / tmp'ye yazmayı deneyin ve bu işe yaradığında oradan gidin.
Jamie Carl

1
Bağlantı, yeniden tasarım nedeniyle artık öldü, buradan geri dönüş
Tony

MVC çerçeveme şimdi eklendi. Bakınız: git.hazaarlabs.com/hazaar/hazaar-thread
Jamie Carl


1

appserverTeknoloji bölümünden hiç haber aldınız mı?

Php ile yazılmıştır ve yüksek trafikli php uygulamaları için çoklu iş parçacıkları yöneten bir uygulama sunucusu olarak çalışır. Hala beta sürümünde ama çok umut verici.


-3

Keneler adı verilen oldukça belirsiz ve yakında kullanımdan kaldırılacak bir özellik var . Şimdiye kadar kullandığım tek şey, bir komut dosyasının SIGKILL (Ctrl + C) yakalamasına ve zarif bir şekilde kapanmasına izin vermekti.


3
Keneler paralel olarak çalışmaz. Esasen, her ifadeden sonra tik fonksiyonunuz çalışır. Onay fonksiyonunuz çalışırken, ana kod çalışmıyor.
Frank Farmer

1
işaretler yalnızca signal () işleyicisi için gereklidir.
Nick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.