Skip to content

多线程(无线程池)

  • 单个线程(随用随仍)

  • 线程池(一上来就开辟空间)

单个线程

  • 配置如下
bash
const ipcApiRoute = {
  dojobonce: "controller.testjob.doJob",
  listenoncejob: "controller.testjob.testjoboncelistener",
};

export { ipcApiRoute };

(1) html

html
<button @click="openjob">开启多线程(无线程池)</button>

(2) js

js
/*里面是监听所有的数据*/
  created() {
    // 多线程监听
    this.initxc();
  },

/* 里面是监听所有的数据 */
/* 开启多线程*/
openjob() {
  let params = {
    id: this.id,
    action: "create",
  };
  ipc.send(ipcApiRoute.dojobonce, params);
},
/* 关闭多线程 */
closejob() {
  let params = {
    id: this.id,
    action: "close",
  };
  ipc.send(ipcApiRoute.dojobonce, params);
},
callbackxc(event, result) {
  console.log("********");
  console.log(result);
},
initxc() {
  ipc.on(ipcApiRoute.listenoncejob, this.callbackxc);
},

(3) 控制器

js
"use strict";

const { Controller } = require("ee-core");
const Log = require("ee-core/log");
const Services = require("ee-core/services");

/**
 * example
 * @class
 */
class TestjobController extends Controller {
  constructor(ctx) {
    super(ctx);
  }

  /**
   * 所有方法接收两个参数
   * @param args 前端传的参数
   * @param event - ipc通信时才有值。详情见:控制器文档
   */

  /**
   * test
   */
  async doJob(params, event) {
    await Services.get("testjob").doJob(params.id, params.action, event);
  }
}

TestjobController.toString = () => "[class TestjobController]";
module.exports = TestjobController;

(4) 服务层

js
// 引入模块

const { ChildJob } = require("ee-core/jobs");
const { Service } = require("ee-core");
const Log = require("ee-core/log");
/**
 * 示例服务(service层为单例)
 * @class
 */
class TestJobService extends Service {
  constructor(ctx) {
    super(ctx);

    // 在构造函数中初始化一些变量
    this.myJob = new ChildJob();
    this.taskForJob = {};
  }

  /**
   * 执行任务
   */
  doJob(jobId, action, event) {
    let res = {};
    let oneTask;
    const channel = "controller.testjob.testjoboncelistener";
    if (action == "create") {
      // 执行任务及监听进度
      let eventName = "job-timer-progress-" + jobId;
      const timerTask = this.myJob.exec("./jobs/testjobs/testjobs", { jobId });
      timerTask.emitter.on(eventName, (data) => {
        Log.info("[main-process] timerTask, from TimerJob data:", data);
        // 发送数据到渲染进程
        event.reply(`${channel}`, data);
      });

      // 执行任务及监听进度 异步
      // myjob.execPromise('./jobs/example/timer', {jobId}).then(task => {
      //   task.emitter.on(eventName, (data) => {
      //     Log.info('[main-process] timerTask, from TimerJob data:', data);
      //     // 发送数据到渲染进程
      //     event.sender.send(`${channel}`, data)
      //   })
      // });

      res.pid = timerTask.pid;
      this.taskForJob[jobId] = timerTask;
    }
    if (action == "close") {
      oneTask = this.taskForJob[jobId];
      oneTask.kill(); // 主动退出杀死进程
      event.sender.send(`${channel}`, { jobId, number: 0, pid: 0 });
    }

    return res;
  }
}

TestJobService.toString = () => "[class TestJobService]";
module.exports = TestJobService;

(5) jobs(多线程)

js
// jobs/testjobs/testjobs.js

const Job = require("ee-core/jobs/baseJobClass");
const Loader = require("ee-core/loader");
const Log = require("ee-core/log");
const Ps = require("ee-core/ps");
const { childMessage } = require("ee-core/message");
const Hello = Loader.requireJobsModule("./example/hello");

/**
 * example - testjob
 * @class
 */
class TestJob extends Job {
  constructor(params) {
    super();
    this.params = params;
  }

  /**
   * handle()方法是必要的,且会被自动调用
   */
  async handle() {
    Log.info("[child-process] TimerJob params: ", this.params);

    // 计时器任务
    let number = 0;
    let jobId = this.params.jobId;
    let eventName = "job-timer-progress-" + jobId;
    let timer = setInterval(function () {
      console.log(JSON.stringify(childMessage));
      childMessage.send(eventName, { jobId, number, end: false });
      number++;
    }, 1000);

    // 用 setTimeout 模拟任务运行时长
    setTimeout(() => {
      // 关闭定时器
      clearInterval(timer);

      // 任务结束,重置前端显示
      childMessage.send(eventName, { jobId, number: 0, pid: 0, end: true });

      // 如果是childJob任务,必须调用 Ps.exit() 方法,让进程退出,否则会常驻内存
      // 如果是childPoolJob任务,常驻内存,等待下一个业务
      if (Ps.isChildJob()) {
        Ps.exit(); // 这个是自然退出
      }
    }, 100 * 1000);
  }
}

TestJob.toString = () => "[class TestJob]";
module.exports = TestJob;