2010-05-29 24 views
1

我有一個PHP CLI腳本,主要寫作功能作爲聊天客戶端連接到聊天服務器(不要問我爲什麼我這樣做在PHP中,這是另一個故事哈哈)。PHP:pcntl_alarm()和socket_select()可以和平地存在於同一個線程中嗎?

我的腳本利用socket_select()函數來掛起執行,直到套接字上發生什麼事,然後喚醒,處理事件並等待下一個事件。現在,我需要每30秒左右執行一些例行任務(檢查是否需要取消配額管理,保存用戶數據庫和其他各種配件)。

從我所知道的,PHP並沒有很好的多線程支持。我的第一個想法是每次套接字生成一個事件並重新獲得程序時,比較一個時間戳,但這是非常不一致的,因爲服務器可能會閒置幾個小時,並且沒有執行任何清理例程。

我遇到了PHP pcntl擴展,它讓我使用SIGALRM分配一個時間間隔來獲取發送,並在每次發送函數時執行該函數。這似乎是我的問題的理想解決方案,但pcntl_alarm()和socket_select()彼此衝突非常糟糕。每次SIGALRM被觸發時,各種瘋狂的事情都發生在我的套接字控制代碼中。

我的程序相當長,所以我不能在這裏發佈它,但它不應該因爲我不相信我在代碼方面做錯了什麼。我的問題是:在等待的socket_select()中,是否有任何方法可以在同一個線程中處理SIGALRM?如果是這樣,怎麼樣?如果不是,我在這裏有什麼替代方案?

這是我的程序的一些輸出。我的報警功能只是輸出「Tick!」每當它被稱爲讓事情發生的時候很容易知道。這是輸出(包括錯誤)允許它剔4倍後(沒有實際嘗試在連接到服務器,儘管它說什麼):

[10年5月28日20時01分05秒@ ]聊天服務器從文件啓動192.168.1.28端口4050

[10年5月28日20時01分05秒@]加載用戶

PHP公告:未定義抵消:0在/ home /丹尼/項目/PHPChatServ/ChatServ.php 112行

PHP警告:socket_select():無法選擇[4]:在/ home/danny/pr中斷系統調用Ojects/PHPChatServ/ChatServ.php on line 116

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

PHP警告:socket_accept():無法接受傳入的連接[4]:中斷系統調用在/home/danny/projects/PHPChatServ/ChatServ.php線126

[10年5月28日@ 20:01:25]滴答! PHP警告:socket_getpeername()期望參數1是資源,在/home/danny/projects/PHPChatServ/ChatServ.php在線129給出的布爾值

[05-28-10 @ 20:01:25]接受從 PHP通知套接字連接:未定義偏移:1 /home/danny/projects/PHPChatServ/ChatServ.php線112上

PHP警告:socket_select():無法選擇[4]:在被中斷的系統呼叫/ home/danny/projects/PHPChatServ/ChatServ.php on line 116

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

PHP警告:socket_accept():無法接受傳入的連接[4]:中斷系統調用在/home/danny/projects/PHPChatServ/ChatServ.php線126

[10年5月28日@ 20:01:45]請勾選!

PHP警告:socket_getpeername()預計參數1是資源,布爾線在給定/home/danny/projects/PHPChatServ/ChatServ.php 129

[10年5月28日20:01 @: 45]從

PHP通知接受插座連接:未定義偏移:2 /home/danny/projects/PHPChatServ/ChatServ.php線112上

回答

2

pcntl_alarmsocket_select可以共存,但你必須意識到如何做到這一點。

特別是,如果警報關閉,而socket_select()正在等待,則在處理警報後,socket_select()將立即返回並顯示錯誤指示。錯誤是「中斷系統調用」,這是你在輸出中看到的。您需要專門檢查該錯誤,然後重試socket_select()

或者,您可以忘記使用鬧鐘,而是使用socket_select()的超時設施。這就是參數tv_sec的作用 - 它在幾秒鐘內給出一個超時,在此之後,即使沒有套接字準備好,socket_select()也會返回。然後你可以進行常規處理。

+0

我相信tv_sec參數對我正在做的事很好 – DWilliams 2010-08-16 14:01:30

相關問題