close

www的興起改變了以往系統平台皆以應用程式為主的設計方式,越來越多的應用程式都搭配上網頁的功能,讓使用者無論身在何處皆能透過瀏覽器來連接系統,而不需要再浪費等待應用程式安裝的時間,也由於網頁語言和UI的關係非常緊密且大部分的網頁語言都屬於透過Interpreter及時解譯的Script Language,使得網頁語言非常的不適合也不應該用於開發需要消耗大量系統運算資源的程式,但是出來混的總有一天要還的,總會有些功能需要由那種能夠處理超大量資料的程式語言如C/C++來開發,抑或者你會需要透過一些現有的程式來幫助你完成一些事情,但是這些程式天殺的沒有API來供你調用,類似這種時候,我們多半都會利用資料介面如資料庫,或者由system、exec等透過Command Argument Passing的方式來完成網頁與AP的介接。

雖然像上面那樣開發程式的方式可能不多見,但是就被我遇到了(之前mantain的一套程式也是這樣透過exec把一些元件包裝成API),我遇到的問題主要是需要對網頁上傳檔案作一些需要耗費相當多功夫的處理,姑且可以想像成把上傳的圖片縮圖、加框蓋上浮水印,反正就是網頁程式沒辦法那麼快處理好的就是了拉,一般遇到這種問題多半有兩種解法,第一種就是叫Client等,就如同你在網頁上面常常看到用AJAX寫成Loading畫面,第二種就是先把檔案存在Server上面,再寫一隻Daemon定期去處理這些檔案,第一種方式是比較不吃系統資源,反正檔案傳上來了我就做,不用隨時常駐一隻Daemon在那裡monitor,而且對用戶來說比較及時,等完了就可以看結果,但是如果需要處理時間非常久的話,用戶會等到起笑,第二種方法則相反。

今天心血來潮在想是不是有折衷方案(其實是懶的去寫Daemon),因為平時在使用unix的時候,一些需要耗時較久的工作我都會把它先丟到背景,晚點再來看結果,結果試了php的exec()跟system()這兩個函數都失敗,二話不說趕快去拜google大神,想不到一下子就找到解決方案了,在php裡面要把shell job丟到背景裡跑的話,可以用popen()跟pclose()這兩個函數,popen會fork一個command process然後回傳pointer,接著php就可以透過這個pointer利用fread、fput等函式來跟fork出來的這個command process溝通,而exec跟system雖然也會create command process,但是這兩個function並沒有辦法在執行時互動,頂多只能輸出執行結果,因此一但用了exec跟system就得等到command執行完畢才會繼續執行其他程式碼,且無法將command process丟到背景執行,所以若你用exec或system執行耗時較久的程式時可能會導致整個主程式等待過久而發生execution timeout,因此,利用popen跟pclose就成了折衷方案,下面是騎蟲企啃米提供的Sample Code:

unix
pclose(popen('usr/bin/php script.php &', 'r'));
windows
pclose(popen("start /b C:\php\cli\php script.php', 'r'));

試用結果非常滿意,改兩行code之後,UI的反應時間提升非常多阿...而且少寫好多程式碼...讚拉。

arrow
arrow
    全站熱搜

    nsysumis94 發表在 痞客邦 留言(1) 人氣()