PHP: pcntl_alarm Can () ve aynı iş parçacığı socket_select () barış var?

1 Cevap php

Ben çoğunlukla chat istemcileri için bir sohbet sunucusu olarak işlev bağlanmak için yazılı bir PHP CLI komut dosyası var (PHP bunu yapıyorum, neden bana sormayın, haha ​​thats başka bir hikaye).

Benim komut dosyası bir şey, o uyanır hangi noktada, bir yuva olur olayı işler ve bir sonraki olaya kadar bekleyeceği kadar socket_select () işlevi yürütme asmak için kullanır. Şimdi, (tempbanned kullanıcılar unbanned gerektiğini kontrol, kullanıcı veri tabanları, diğer çeşitli şeyler kaydetmek), her 30 saniye kadar gerçekleştirilen gereken bazı rutin görevler vardır.

Ne söyleyebilirim PHP, hepsi de çok büyük çok-Threading desteği yok. Benim ilk düşünce bir zaman damgası soket bir olay oluşturur ve program yeniden akan alır her zaman karşılaştırmak oldu, ama sunucu çok iyi benim temizleme rutinleri herhangi idam zorunda saat boyunca boşta oturup olamazdı çünkü bu çok tutarsız.

Ben PHP PCNTL uzantıları geldi ve bana gönderilen her zaman gönderilen almak ve bir fonksiyon icra olsun SIGALRM için bir zaman aralığı atamak kullanmanızı sağlar. Bu oldukça kötü birbirleri ile ancak pcntl_alarm () ve socket_select () çatışması, benim sorunum için ideal bir çözüm gibi görünüyor. Her zaman SIGALRM tetiklenir, çılgınca şeyler her türlü benim soket kontrol kod olur.

Benim program dolayısıyla burada bütün açamazsınız oldukça uzundur, ama ben kod bilge yanlış bir şey yapıyorum inanmıyorum çünkü önemli olmamalı. Benim soru: bir bekleme socket_select olarak aynı iş parçacığı ele alınması gereken bir SIGALRM için herhangi bir yolu var mı (?) Eğer öyleyse, nasıl? Değilse, benim alternatifleri burada nelerdir?

İşte benim programdan bazı çıktı bulunuyor. Benim alarm fonksiyonu sadece "Tick!" Çıktılar o şeyler oluyor zaman kolay anlatmak için yapmak denir zaman. Bu 4 kez kene beklendikten sonra (hatalar dahil) çıktı (hiçbir gerçek girişimleri ne diyor rağmen sunucuya bağlanırken orada değildi):

[20:01:05 @ 05-28-10] Sohbet sunucusu 192.168.1.28 port 4050 başladı

[20:01:05 @ 05-28-10] dosyadan 2 kullanıcıları Yüklendi

PHP Notice: 0 home / danny / projects / PHPChatServ / ChatServ.php / on line 112: offset Undefined

PHP Uyarı: socket_select (): 116 hattı üzerinde / home / danny / projects / PHPChatServ / ChatServ.php Engellenen sistem çağrısı: [4] seçememişse

[20:01:15 @ 05-28-10] Kene!

PHP Uyarı: socket_accept (): Gelen bağlantıyı kabul edemiyoruz [4]: ​​Engellenen sistem çağrısı ev / danny / projects / PHPChatServ / ChatServ.php / on line 126

[05-28-10 @ 20:01:25] Tick! PHP Uyarı: socket_getpeername () parametre 1 kaynak olmasını beklediğini, on line ev / danny / projects / PHPChatServ / ChatServ.php / verilen Boole 129

[05-28-10 @ 20:01:25] Accepting socket connection from PHP Notice: Undefined offset: 1 in /home/danny/projects/PHPChatServ/ChatServ.php on line 112

PHP Uyarı: socket_select (): 116 hattı üzerinde / home / danny / projects / PHPChatServ / ChatServ.php Engellenen sistem çağrısı: [4] seçememişse

[20:01:35 @ 05-28-10] Kene!

PHP Uyarı: socket_accept (): Gelen bağlantıyı kabul edemiyoruz [4]: ​​Engellenen sistem çağrısı ev / danny / projects / PHPChatServ / ChatServ.php / on line 126

[20:01:45 @ 05-28-10] Kene!

PHP Uyarı: socket_getpeername () parametre 1 kaynak olmasını beklediğini, on line ev / danny / projects / PHPChatServ / ChatServ.php / verilen Boole 129

Dan [20:01:45 @ 05-28-10] kabul soket bağlantısı

PHP Notice: 2 ev / danny / projects / PHPChatServ / ChatServ.php / on line 112: offset Undefined

1 Cevap

pcntl_alarm ve socket_select arada, ama bunu doğru yapmak için nasıl farkında olmak gerekiyor olabilir.

Özellikle, alarm kapalı giderse socket_select() alarm socket_select() bir hata göstergesi ile hemen dönecektir işlenir sonra sonra, beklerken. Hatası çıktı görüyorsanız ne "Interrupted Sistemi Çağrı" dır. Bunu özellikle bu hata için kontrol ve socket_select() yeniden denemek gerekir.

Alternatif olarak, sadece alarmı kullanarak unutun ve yerine socket_select() zaman aşımı tesis kullanabilirsiniz. Bu tv_sec parametre için ne olduğunu - hiçbir yuva hazır olsa bile socket_select() dönecektir sonra, zaman aşımını saniye olarak verir. Daha sonra normal işlem yapabilirsiniz.