ちきさんです。
Node.jsでCPUコアをフルに使って負荷の高い処理ができるかなと思ったのでやってみました。
cluster APIを使って書いています。
APIの使い方が正しいかどうかはわかりませんが、loadSize
を大きい数字にするとCPUファンがガンガン回るので楽しいです。
super-power.ts
import * as cluster from 'cluster'
import { Subject } from 'rxjs/Rx'
const numCPUs = require('os').cpus().length
interface Message {
pid: number
value: number
}
function superPower(): Promise<number[]> {
const queue$: Subject<number[]> = new Subject()
let finishCount: number = 0
for (let i = 0; i < numCPUs; i++) {
cluster.fork()
}
cluster.on('exit', (worker) => {
console.log(`worker ${worker.process.pid} died`)
})
cluster.on('message', (worker, message) => {
console.log(`message: ${JSON.stringify(message)} from ${worker.id}`)
queue$.next(message.value)
if (++finishCount === numCPUs) {
cluster.disconnect() // Workerをシャットダウンする。
queue$.complete() // このタイミングでこの関数の戻り値が返される。
}
})
return queue$
.startWith([])
.reduce((p, value) => p.concat(value))
.toPromise()
}
function workWorkWork(): void {
const loadSize: number = Math.round(Math.random() * 10000000000)
let temp = 0
// CPUコアに負荷をかける。
for (let i = 0; i < loadSize; i++) {
temp = temp + i
}
const message: Message = { pid: process.pid, value: loadSize }
process.send!(message)
}
if (cluster.isMaster) {
superPower()
.then(value => {
console.log('result:', value)
})
} else {
workWorkWork()
}
出力はこんな感じ。
OUTPUT
message: {"pid":79291,"value":1039512909} from 5
message: {"pid":79289,"value":2097703303} from 3
message: {"pid":79287,"value":3289584265} from 1
message: {"pid":79290,"value":4997136338} from 4
message: {"pid":79288,"value":6719233976} from 2
message: {"pid":79292,"value":7072344527} from 6
message: {"pid":79293,"value":8830078665} from 7
message: {"pid":79294,"value":8978470370} from 8
result: [ 1039512909,
2097703303,
3289584265,
4997136338,
6719233976,
7072344527,
8830078665,
8978470370 ]
worker 79288 died
worker 79291 died
worker 79290 died
worker 79292 died
worker 79293 died
worker 79289 died
worker 79287 died
worker 79294 died