Javascript Can';我设置好信号后不能关掉吗?
当执行上述代码并将SIGINT传递给进程时,进程将由第一个SIGINT恢复 但问题是, 信号处理后,, SIGINT不再工作了 所以,我试着让它工作Javascript Can';我设置好信号后不能关掉吗?,javascript,signals,deno,Javascript,Signals,Deno,当执行上述代码并将SIGINT传递给进程时,进程将由第一个SIGINT恢复 但问题是, 信号处理后,, SIGINT不再工作了 所以,我试着让它工作 let sig = Deno.signal(Deno.Signal.SIGINT) await sig console.log('hi') 这就是我得到的: sig.dispose在sig出现wait时立即解决sig(无论是否交付SIGINT) 对于asyncierator,它意味着返回done:true 它与将SIGINT返回其原始状态无关
let sig = Deno.signal(Deno.Signal.SIGINT)
await sig
console.log('hi')
这就是我得到的:
sig.dispose
在sig
出现wait
时立即解决sig
(无论是否交付SIGINT)
对于asyncierator
,它意味着返回done:true
它与将SIGINT返回其原始状态无关
这是有意的吗?通常预期的处理信号流的方法如下:
const sig=Deno.signal(Deno.signal.SIGINT);
//注意:您可能希望同时运行一个任务来测试这个。
//在这种情况下,信号属于可选/未兑现承诺的类型
//这样的承诺不会阻止运行时退出。
//出于测试目的,您可能需要添加下面的行。
setTimeout(()=>{},100000);
//异步迭代器。您可能可以将其包装在一个函数中,这样它就不会
//块顶级执行
等待(信号常数){
console.log(“捕获的SIGINT”);
}
SignalStream
由Deno.signal
返回,确实有一个。然后方法,这样您也可以使用此样式:
const sig=Deno.signal(Deno.signal.SIGINT);
setTimeout(()=>{},100000);
while(true){
等待信号;
console.log(“捕获的SIGINT”);
}
它应该起作用,需要等待多次。以下示例在3个SIGINT触发器(本地验证为工作)后正确退出流程:
const sig=Deno.signal(Deno.signal.SIGINT);
const timeout=setTimeout(()=>{},100000);
等待信号;
console.log(“捕获的SIGINT#1”);
等待信号;
console.log(“捕获的SIGINT#2”);
等待信号;
console.log(“信号捕获#3,退出”);
clearTimeout(超时);
控制台日志(“完成”);
如问题所示,sig.dispose()
,确实完成了从sig
解除信号绑定的工作,并使等待的承诺立即被唤醒。这是为了允许异步迭代器立即退出循环(如果有)。调用.dispose()
后,原始的sig
不再可用(因为备份信号资源已关闭并从内部资源表中删除)。您必须再次调用Deno.signal(Deno.signal.SIGINT)
来创建一个新的sig
const sig1=Deno.signal(Deno.signal.SIGINT);
const exitBlocker=setTimeout(()=>{},100000);
等待信号1;
log(“sig1.sig1接收到的SIGINT”);
sig1.dispose();
const sig2=Deno.signal(Deno.signal.SIGINT);
等待信号1;//这应该立即解决,即使没有信号
log(“sig1立即解析,但没有实际信号发生”);
等待sig2;
log(“sig2收到SIGINT,这是真正的交易。”);
等待sig2;
log(“sig2再次收到SIGINT。准备退出”);
clearTimeout(exitBlocker);
控制台日志(“完成”);
如果在上面本地运行,您将看到以下内容:
let sig = Deno.signal(Deno.Signal.SIGINT)
await sig
sig.dispose()
console.log('hi')
非常感谢您的详细解释。但我真正关心的是,在上面的示例中(没有定义sig2),在没有清除exitBlocker的情况下,即使发送额外的SIGINT,进程也不会停止。(你必须等待拦截器自身结束,或者发送SIGKILL)@Kwonryl我记得这是由于我们使用atm的底层铁锈板条箱(Tokio)造成的一些怪癖。我简单地浏览了Tokio的底层代码,甚至是它的上游信号钩子注册表,并注意到一旦注册了一个信号,即使所有处理程序都被删除了,默认值也永远不会恢复(他们永远不会重新应用SIG_DFL
):这是团队可以讨论的一件有趣的事情,但现在我们不得不忍受它(signal()
不稳定,因此可能会有更改)@kwonryl提交问题以进行跟踪:
^CSIGINT received by sig1. Disposing sig1
sig1 resolves immediately, but no actual signal happened
^CSIGINT received by sig2. This is the real deal.
^CSIGINT received by sig2 again. Preparing for exit.
DONE