Nodejs



thread

testThread.js

'use strict'
//--- Node.js 10.5 버전부터 thread pool에서 사용자가 thread를 생성할 수 있습니다.
const { Worker, isMainThread, parentPort, threadId, workerData, MessageChannel } = require('worker_threads');

class TestThread {
    run() {
        console.log('zztest/testThread.js :: start');
        let data = {
            workerData: {                                   //--- 이값이 workerData로 전달 된다.
                num: 1000000
            }
        };

        let myWorker001 = new Worker(__dirname + '/testThreadWorker.js', data);

        myWorker001.on('message', (msg) => {                //--- once. 한번만 실행, on. 계속 실행 대기
            console.log(`zztest/testThread.js :: message for myWorker001 - ${JSON.stringify(msg)}`);
        });
        myWorker001.on('error', (err) => {
            console.log(`zztest/testThread.js :: myWorker001 error - ${JSON.stringify(err)}`);                
        });
        myWorker001.on('exit', (code) => {                  //--- code = 0. 정상
            console.log(`zztest/testThread.js :: myWorker001 exit code - ${code}`);                
        });



        data.workerData.num = 2000000;
        let myWorker002 = new Worker(__dirname + '/testThreadWorker.js', data);

        myWorker002.on('message', (msg) => {                //--- once. 한번만 실행, on. 계속 실행 대기
            console.log(`zztest/testThread.js :: message for myWorker002 - ${JSON.stringify(msg)}`);
        });
        myWorker002.on('error', (err) => {
            console.log(`zztest/testThread.js :: myWorker002 error - ${JSON.stringify(err)}`);                
        });
        myWorker002.on('exit', (code) => {                  //--- code = 0. 정상
            console.log(`zztest/testThread.js :: myWorker002 exit code - ${code}`);                
        });



        //--- MessageChannel : port2는 하나의 worker로만 전달이 가능 하다.
        const { port1, port2 } = new MessageChannel();
        port1.on('message', (msg) => {                //--- once. 한번만 실행, on. 계속 실행 대기
            console.log(`zztest/testThread.js :: portForMain - ${JSON.stringify(msg)}`);
        });
        myWorker001.postMessage({ greeting: 'Hello worker 1', port: port2 }, [port2]);  //--- MessageChannel 사용시 두번째 parameter는 필수
        myWorker002.postMessage({ greeting: 'Hello worker 2' });



        console.log('zztest/testThread.js :: Thread information');
        console.log('    isMainThread : ' + isMainThread);                      //--- true
        console.log('    threadId : ' + threadId);                              //--- 0
        console.log('    parentPort : ' + JSON.stringify(parentPort));          //--- null
        console.log('    workerData : ' + JSON.stringify(workerData));          //--- data.workerData 값이 전달됨

        console.log('zztest/testThread.js :: stop');
        console.log(' ');
    }
}

let appl = new TestThread();

appl.run();

testThreadWorker.js

'use strict'
const { isMainThread, parentPort, threadId, workerData } = require('worker_threads');

class TestThreadWorker {
    run() {
        console.log(`zztest/TestThreadWorker.js :: start - ${threadId}`);

        let sum = 0;
        for (let idx = 0; idx < workerData.num; idx++) {
            sum = sum + idx;
        }

        console.log(`zztest/TestThreadWorker.js :: Thread information - ${threadId}`);
        console.log('    isMainThread : ' + isMainThread);                      //--- false
        console.log('    threadId : ' + threadId);                              //--- 1, 2, 3, ...
        console.log('    parentPort : ' + JSON.stringify(parentPort));          //--- {"_events":{},"_eventsCount":2}
        console.log('    workerData : ' + JSON.stringify(workerData));          //--- data.workerData 값이 전달됨

        parentPort.once('message', (msg) => {               //--- once. 한번만 실행, on. 계속 실행 대기
            console.log(`zztest/TestThreadWorker.js :: message for myWorker00${threadId} - ${msg.greeting}`);

            if (threadId == 1) {
                //--- MessageChannel 사용시
                const { port } = msg;
                port.postMessage({ greeting: `Hello main. I am worker ${threadId}.`});
            }
        });
        parentPort.postMessage({ sum: sum });

        if (threadId == 2) {
            // process.exit(3);                                //--- 에러 코드를 지정하여 에러 발생
            // Worker.terminate();                             //--- 에로 코드 1
            // zzError                                         //--- 에로 코드 1
        }

        console.log(`zztest/TestThreadWorker.js :: stop - ${threadId}`);
        console.log(' ');
    }
}

let appl = new TestThreadWorker();

appl.run();

Last modified, 2020.02.09 ~ 2020.02.09, version 0.01

최종 수정일: 2022-10-24 19:17:28

이전글 :
다음글 :
상단 menu
arrow_back_ios
arrow_forward_ios