3

我使用PhantomJS,一種命令行工具來渲染網站圖像,並且我想並行執行一些命令行,而不是一個接一個地執行。我怎樣才能做到這一點?在Ruby中並行運行命令行進程

+0

您可以簡單地使用Thread.new do ... end – apneadiving

+0

很酷,這與第一個答案提供的解決方案相比如何? –

+0

以及使用纖維代替螺紋? –

回答

3

以下是使用Resque的示例。注意爲了簡潔起見,我已經逃離了......你應該從來沒有直接將外部輸入傳遞給shell命令。

class RasterizeWebPageJob 
    @queue = :screenshots 
    def self.perform(url) 
    system("/usr/bin/env DISPLAY=:1 phantomjs rasterize.js #{url} ...") 
    end 
end 

10.times { Resque.enqueue(RasterizeWebPageJob, "http://google.com/") } 

如果您運行的工人數量足夠多(並且有工人可用),他們將並行執行。這裏最重要的是你將單獨的作業放到隊列中,而不是在一個作業中處理多個屏幕截圖。

我建議不要在Rails控制器中使用Thread.new。隊列比線程更容易管理(並且更安全)。

+0

Resque vs Threads的性能如何? –

+0

和有什麼區別? –

+0

性能可能會變差,因爲您需要運行Resque,儘管它使用快速分叉模型,但會增加進程開銷。線程真的是一個壞主意......他們共享相同的內存空間,如果你沒有經驗寫多線程程序會導致一些很難找到的錯誤。如果一個線程崩潰,你的整個過程就會崩潰,很難確定運行什麼,什麼不運行。 Resque(和其他排隊解決方案)專門用於使管理長時間運行的作業更簡單,更加友好。 – d11wtq

1

有多種方法可以做到這一點。你正在尋找的是在後臺做異步作業。此視頻可能有所幫助:http://railscasts.com/episodes/128-starling-and-workling

+0

不錯......所以如果我在一個迭代了許多shell命令的worker中運行'each'循環,它們會並行運行? –

+0

並且每個循環都需要進入工人內部還是在你稱之爲工人的地方? –

0

我想這些其他答案可能會丟失的是提供一個設計模式的基礎教育,你會想要使用。是的,Resque或Starling和Workling或Resque與Foreman結合將是很好的解決方案,但您可能想知道爲什麼。

我相信你想要使用的模式是觀察者模式或發佈者訂閱者或PubSub,縮寫。這個想法與最簡單情況下打印機的工作方式類似。

一個人(出版商)點擊打印在一個網頁瀏覽器。然後,打印機異步地打印它們。如果打印機沒有打開,它將在打開時收到消息。如果多人將文檔發送到打印機,打印機將按順序選擇它們(FIFO),然後處理(打印)它們。如果有多臺打印機監聽同一個隊列(這是因爲你通常沒有這個比喻而導致比喻崩潰的地方),那麼他們可以依次選擇消息來更快地處理隊列。

Resque和其他PubSub的寶石,項目,JAR(你不限於Ruby)實現這種設計模式。對這裏的模式

更多信息(注意,Java的可觀測是一個類,這是一個不好的設計決策,您可以實現自己的。):

http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html http://docs.oracle.com/javase/7/docs/api/java/util/Observable.html http://en.wikipedia.org/wiki/Observer_pattern http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern

對於我們的處理,我們使用Resque來處理較小的任務,但是您仍然侷限於全局解釋器鎖定以及其他問題,例如必須將代碼部署到服務器,安裝寶石等。我們現在使用Storm(https://github.com/nathanmarz/storm)來處理我們的流處理,它工作窪你好。根據你一天處理的圖像數量,風暴對你想要做的事情可能是過度的。