中断while()并优雅地完成Node.js

时间:2016-01-16 15:13:49

标签: javascript node.js

我正在为旅行商问题实施随机抽样/蒙特卡罗启发式算法。 我希望执行最大c次迭代,同时能够通过 Ctrl + C 或将SIGINT发送到我的进程时停止搜索

我知道之前已经问过这个问题(相关:Quitting node.js gracefully)但是给定的解决方案对我不起作用。当我给出 Ctrl + C 时,该过程不会退出,如果我将其删除,则不会执行最终化代码。

我的代码:

var tsp = require("./Tsp.js");
var data = tsp.load("./input/it16862.tsp");

var starting_point = data.splice(10927, 1)[0];
var c = 0;
var cost = Number.POSITIVE_INFINITY;
var new_cost, solution, candidate_solution;
var interrupt = false;
var c = 0, interrupt = false;

process.on('SIGINT', function() {
    interrupt = true;
});

while(c < 1000000000) {
    if (interrupt) {
        break;
    }
    candidate_solution = shuffle(data);
    new_cost = tsp.cost(candidate_solution, starting_point);
    if (new_cost < cost) {
        cost = new_cost;
        solution = candidate_solution;
        console.log("Found a new better solution! %d", cost);
    }
    c++;
}

if (interrupt) {
    console.log("Caught interrupt signal");
}
console.log("Examined %d solutions", c);
console.log("Best: %j", cost);
console.log("Solution written to: %s", tsp.write(solution, starting_point, cost));

我在Ubuntu 14.04.1Nodejs 4.2.4。知道什么可能是错的吗?

1 个答案:

答案 0 :(得分:1)

JavaScript是一种单线程语言,因此运行时无法像这样在while循环中间中断进程。在主事件循环空闲之前,不会调用process.on处理程序函数,这在c >= 1000000000之前不会发生,因为你永远不会屈服。

为了使其工作,您需要更改工作循环以偶尔回到Node.js运行时,如下所示:

// ...
var c = 0, interrupt = false;
function doWork() {
  while(c < 1000000000) {
      if (interrupt) {
          break;
      }
      // yield every 10000 iterations to
      // allow the event loop to handle events
      if ((c % 10000) === 0) {
          setImmediate(doWork);
          return;
      }
      candidate_solution = shuffle(data);
      new_cost = tsp.cost(candidate_solution, starting_point);
      if (new_cost < cost) {
          cost = new_cost;
          solution = candidate_solution;
          console.log("Found a new better solution! %d", cost);
      }
      c++;
  }
}

doWork();

您可以通过为产量之间的迭代次数选择不同的值来调整性能与响应性(较高的数字可以通过避免由屈服引起的开销来提高性能,但通过使其花费更长的时间直到可以确认中断来降低响应性)。 / p>