簡體   English   中英

Node.js 中多線程進程的返回值

[英]Return value from multithreaded process in Node.js

我設計了一個 function diversify()來獲取一些昂貴的 function f()並在運行它的機器的所有內核上並行運行它。 我還設置了這個,如果f()在一個內核上返回一個值,所有其他線程都會自動終止。 代碼如下:

let diversify = f => {
    // Split a function `f` into a thread for each core of the machine.
    // The first thread to finish will return its result and end all others.
    
    if ( cluster.isMaster ) {

        let children = []
        for ( let i = 0; i < os.cpus().length; i++) {
            children.push(cluster.fork())
        }

        cluster.on('message', (_, msg) => {

            if ( msg.cmd == 'stop' ) { children.forEach(child => {
                child.process.kill()
            })}

            return msg.out

        })

    } else {

        let out = f()
        process.send({ cmd: 'stop', out })

    }

}

問題是在一個進程通過msg.cmd = 'stop'告訴主進程停止后,沒有辦法返回 output msg.out 在上面的代碼中實現它的方式, return msg.out語句位於匿名 function 嵌套在更大的多樣化 function 中。 因此,當您運行諸如diversify(() => { return true })之類的東西時,不會公開此返回值,而是導致undefined 有沒有辦法返回msg.out中發送的內容?

向工作人員發送消息是設計為異步的。

從技術上講,沒有辦法從作為事件處理程序的回調中return值,因為事件可能隨時發生。

這個問題的典型解決方案是通過promises 只需將 function 主體包裝在 promise 中並resolve值而不是返回它。

const diversify = (f) =>
    new Promise((resolve) => {
        // Split a function `f` into a thread for each core of the machine.
        // The first thread to finish will return its result and end all others.

        if (cluster.isMaster) {
            let children = [];
            for (let i = 0; i < os.cpus().length; i++) {
                children.push(cluster.fork());
            }

            cluster.on('message', (_, msg) => {
                if (msg.cmd == 'stop') {
                    children.forEach((child) => {
                        child.process.kill();
                    });
                }
                resolve(msg.out);
            });
        } else {
            let out = f();
            process.send({ cmd: 'stop', out });
        }
    });

然后可以在out中訪問結果:

const getPid = () => {
    return process.pid;
};

diversify(() => {
    console.log(getPid());
    return true;
}).then((out) => {
    console.log(out); // true
});

// or using async/await

const diversifyAsync = async () => {
    const out = await diversify(() => {
        console.log(getPid());
        return true;
    });

    console.log(out); // true
};

diversifyAsync();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM