Node 雖然自身存在多個線程,但是運行在 v8 上的 JavaScript 是單線程的。Node 的 child_process 模塊用于創建子進程,我們可以通過子進程充分利用 CPU。范例:
這里了解一下包括 fork 在內的幾個進程創建方法:
1.spawn(command, [args], [options]),啟動一個新進程來執行命令 command,args 為命令行參數
2.exec(command, [options], callback),啟動一個新進程來執行命令 command,callback 用于在進程結束時獲取標準輸入、標準輸出,以及錯誤信息
3.execFile(file, [args], [options], [callback]),啟動一個新進程來執行可執行文件 file,callback 用于在進程結束時獲取標準輸入、標準輸出,以及錯誤信息
4.fork(modulePath, [args], [options]),啟動一個新進程來執行一個 JavaScript 文件模塊,這時候創建的是 Node 子進程
Node 進程間通信
父進程
子進程
需要注意的是,這里的 send 方法是同步的,因此不建議用于發送大量的數據(可以使用 pipe 來代替,詳細見:http://nodejs.org/api/all.html#child_process_child_process_spawn_command_args_options)。
特殊的情況,消息中 cmd 屬性值包含 NODE_ 前綴(例如:{cmd: ‘NODE_foo'} 消息),那么此消息不會被提交到 message 事件(而是 internalMessage 事件),它們被 Node 內部使用。
send 方法的原型為:
這里,sendHandle(handle)可以被用于發送:
1.net.Native,原生的 C++ TCP socket 或者管道
2.net.Server,TCP 服務器
3.net.Socket,TCP socket
4.dgram.Native,原生的 C++ UDP socket
5.dgram.Socket,UDP socket
send 發送 sendHandle 時實際上不是(也不能)直接發送 JavaScript 對象,而是發送文件描述符(最終以 JSON 字符串發送),其他進程能夠通過這個文件描述符還原出對應對象。
現在看一個例子:
父進程
子進程
通過端口 7000 訪問此程序,得到輸出可能為 connection – parent 也可能得到輸出 connection – child。這里子進程和父進程同時監聽了端口 7000。通常來說,多個進程監聽同一個端口會引起 EADDRINUSE 的異常,而此例的情況是,不同的兩個進程使用了相同的文件描述符,且 Node 底層在監聽端口時對 socket 設置了 SO_REUSEADDR 選項,這使得此 socket 可以在不同的進程間復用。在多個進程監聽同一個端口時,同一時刻文件描述符只能被一個進程使用,這些進程對 socket 的使用是搶占式的。
cluster 模塊
在 Node 的 v0.8 新增了 cluster 模塊,通過 cluster 模塊能夠輕松的在一臺物理機器上構建一組監聽相同端口的進程。范例:
我們在 worker 進程中調用 listen 方法,監聽請求將會傳遞給 master 進程。如果 master 進程已經存在一個正在監聽的 server 符合 worker 進程的要求,那么此 server 的 handle 將會傳遞給 worker,如果不存在,master 進程則會創建一個,然后將 handle 傳遞給 worker 進程。
更多詳細的關于 cluster 的文檔:http://www.nodejs.org/api/cluster.html
新聞熱點
疑難解答
圖片精選