2016-04-27 30 views
0

我正在爲Node編寫一個簡單的基於消息的管理器/工作者(http://lya.fciencias.unam.mx/jloa/patrones/MW.html)模塊。通常,在多線程環境中,修改數據的代碼需要鎖定以防止其他線程更改數據中間例程,從而導致混淆競爭條件。例如:在管理員/工作模式中使用子進程以確保線程安全時,Node.js中是否需要鎖定?

function assignWork(job) { 
    if (!this.isWorkComplete && this.workerQueue.length != 0) { 
     this.workerQueue.pop().runJob(job); 
    } 
} 

上面的代碼,在多線程環境中,將需要的鎖,因爲它可能是另一個線程將清空這線程檢查它被填充和時間之間的工作隊列它將工作人員從隊列中彈出,導致錯誤。

但是,我的理解是,因爲Node使用單個事件隊列,所以同步代碼不可能有上述問題,因爲一次只能執行一個線程。

這個假設是否正確?而且,如果Node對於Node來說是正確的,那麼是否存在其他使用多線程的實現,並且需要鎖定機制來確保線程安全?

回答

1

the Node 6.0.0 documentation

的Node.js的單個實例在單個線程上運行。爲了獲得多核系統的優勢,用戶有時會想要啓動一個Node.js進程集羣來處理負載。

Javascript是單線程的,所以在當前任何正確的javascript引擎中都沒有線程安全問題。

到目前爲止,我們在Javascript中唯一真正的多線程是Web工作者。它們使用消息傳遞進行通信,因此它們不共享內存(至少不會顯示給javascript開發人員;引擎可能)。

競爭條件在單線程環境中仍然非常有可能。回調可能會很棘手。

+0

我的理解是,Node的child_process與[link](https://nodejs.org/api/child_process.html)的工作方式類似:「請記住生成的Node.js子進程非常重要獨立於父節點,除了在兩者之間建立的IPC通信通道之外,每個進程都有自己的內存和自己的V8實例。「然而,我所描述的問題並不涉及子進程在Manager中編輯數據(因爲缺少共享內存,他們不能),而且我需要鎖定的函數是同步的。在這種情況下,它是否是線程安全的? – Will

+0

你在JavaScript中做的任何事情都是線程安全的,但是如果你正在激化多個事件,你可能仍然會遇到競爭條件。所以是的,它是線程安全的。總是。 –

1

是的,Filip是絕對正確的,Node.js通過內部多線程提供單線程接口來運行javascript代碼,因此每個操作都是線程安全的。我沒有遇到任何競爭條件的情況,因爲系統中沒有第二方與之競爭。對於這個問題,請注意,在語言語義本身中,共享數據操作邏輯中的'通常的嫌疑犯'(例如同步,互斥,易失性,監視器,屏障,信號量等)是不存在的。希望這給你足夠的證據和信心。底線是節點程序員不會擔心混亂的訪問(多線程)而不是無序(異步)訪問數據。

相關問題