Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Can';我设置好信号后不能关掉吗?_Javascript_Signals_Deno - Fatal编程技术网

Javascript Can';我设置好信号后不能关掉吗?

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返回其原始状态无关

当执行上述代码并将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返回其原始状态无关


这是有意的吗?

通常预期的处理信号流的方法如下:

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