2008-09-25 197 views
1

我有一個每分鐘從一個cron作業調用的PHP腳本。該腳本從數據庫中獲取一些信息,然後使用System函數調用另一個PHP腳本(傳遞一些參數)。不要等待進程退出

這意味着我可以從這個「主」一個啓動10個腳本。我想要做的是我會調用腳本並繼續執行主腳本,也就是說,不要等待系統調用完成,然後再調用下一個腳本。

這怎麼辦?

回答

3

您或許可以使用proc_open(),stream_select()stream_set_blocking()來實現這樣的事情。

如果這聽起來含糊不清,我會在這裏粘貼一大塊代碼,我在最近的一個項目中使用了類似的東西,但後來覺得它可能會阻礙而不是幫助!綜上所述,雖然,代碼工作就像這樣:

  1. 的cronjob cronjob_wrapper.php調用
  2. cronjob_wrapper.php創建一個新的管理類,然後調用它開始
  3. Manager類的啓動方法檢查以查看有多少實例正在運行(查找特定位置中的pid文件)。如果它小於給定的最大數量的實例,它會將它自己的進程ID寫入一個pid文件,然後進行
  4. 管理類創建適當的編碼器類的實例,並調用exec
  5. exec方法使用proc_open,stream_select和stream_set_blocking以非阻塞的方式運行系統命令(在這種情況下運行ffmpeg - 可能需要相當長的一段時間!)
  6. 當它終於運行時,清理它的PID文件並保留。

現在,我被模糊和handwavy的原因是我們這裏的多個實例正在由cronjob而不是由PHP處理。我試圖做很多你正在談論的事情,並得到了與pcntl_fork()和朋友很好的工作,但最終我遇到了一些問題(如果我記得至少有一個是PHP中的錯誤)並決定這種方法是實現同樣目標的更堅定的方法。因人而異。

雖然值得看看這些功能,但可以與他們取得很多成就。雖然不知何故,我不認爲PHP將成爲選擇的插座編程語言... :)

+0

在action中看到stream_select()我有一個庫可以發出非阻塞http請求(想一想ping),看看這裏:http://drupal.org/project/httprl。它適用於Drupal,但只需進行一些微小的更改就可以自行運行。 – mikeytown2 2012-02-22 01:03:55

-1

使用php的fork或線程版本。

+0

PHP不支持線程,但fork()在這裏是一個可接受的選項。 – Rob 2008-09-25 22:04:54

1

如果您的操作系統支持它,您可以使用pcntl_fork()函數來剝離父級不等待的子進程。但要小心,很容易意外地創建太多的子進程,特別是如果它們花費的時間超過預期的運行時間!

0

我不確定PHP是否支持線程。檢查here

-1

你可以在後臺運行它們:

system('php yourscript.php &'); 

你一定要確保你對正在運行的進程總數檢查。總而言之,不是一個超級優雅的解決方案。相反,你可以讓一個腳本永遠運行,我想這樣的事情:

<?php 
while(true) { 
    // do whatever needs to be done. 
} 
?> 

雖然小心。 PHP並不完全知道被用作守護進程。

+3

不適用於我。這個腳本`<?php system(「sleep 5 &"); echo」Test「;?>`在編寫測試消息前還睡5秒 – Gart 2010-07-07 12:40:49