如果您是一位忠实的读者(我敢肯定有几个这样的读者),那么您就会知道超时,取消和异步是我无穷无尽的迷恋源泉。 我遇到了Nathaniel Smith的一系列帖子,他发现Python异步库Trio十分有趣。
对人类和Go的 超时和取消 声明均被认为有害 。通过详细分析各种语言和系统中的并发,异步,取消和超时机制,激励了Trio的设计。 将各种系统与他在Trio中构建的机制进行比较有助于弄清各种系统中的差异和问题。 即使您从未遇到过Python或Trio,这也使之成为一个有趣的分析。
我将不做全面审查,但确实想提出一些我认为特别有趣或可能引起争议的观点,无论是在Trio还是他所比较的系统中。
- 我觉得很有趣,三重奏设计的卖点之一是“ Control-C works”! 也就是说,如果您运行Python程序并尝试在命令行中通过键入Control-C杀死它,它将正确地杀死该程序。 我发现这特别有趣,因为当Sun在1984年发布NFS时,最初的beta实现无法“正确”处理Ctrl-C(SIGINT)。 为了使其按预期方式工作并且对本地文件IO透明,他们需要确保对网络文件系统上的任何IO操作都可以立即正确地正确返回EINTR,以便随后可以由周围环境正确处理该中断以最终终止程序。 因此33年后,正确的取消行为仍然是异步库的卖点。 取消非常困难。
- 有趣的是,试图定义一致机制的各种语言和框架面临的挑战之一是,许多最基本的系统原语都没有提供适当的控制以实现合理的更高级别的模型。 对于Windows来说,这是一个巨大的问题,因为最基本的文件句柄和网络操作(如CreateFile)没有提供正确的控制级别来支持灵活的取消模型。 其他语言和系统也是如此。 最低层缺乏适当的控制往往会蔓延开来,因此其他库和中间件也忽略了这些问题。 所有这些使应用程序开发人员很难对程序行为承担最终责任,以使其一切正常。 在日常使用行为不当的情况下,这种后果会发挥出来。
- Smith关于可组合性的讨论很重要-可组合的行为对于这些设计问题非常重要-但我认为他错过了将设计扎根于现实世界中失败的发生方式及其对设计的影响的基础。 特别是,他关于基于时间间隔的超时与绝对期限的相对行为的讨论遗漏了一个关键点。 大多数面向用户的应用程序都不想使用严格的截止日期,而是希望它们不断发展(并且很可能会向用户提供反馈)。 “我正在(缓慢)进步”和“我一点都没有连通性”之间的区别使一切都变得不同。 这意味着,即使您有一棵超时限制的呼叫树,也很可能将相同的超时应用于每个单独的呼叫,而不是像严格的截止期限那样有效地在两次呼叫之间分割超时。 实际上,使用Trio提供的机制很难实现此行为,因为同时支持可组合性和信息隐藏(因此内部实现细节对调用者隐藏)的需求使得难以在适当的位置重置取消条件。
- 我还将注意到,如果您在服务/数据中心环境中使用此功能,则故障模型(以及因此要使用取消和超时的方式)将大不相同。 如果电池信号不稳定,则所需的行为与尝试与数据中心内同一机架上的服务联系的所需行为完全不同。
- 他通过使用有效的全局取消上下文堆栈而不是显式上下文参数来激励,因为以前的许多系统都具有显式上下文来统一且一致地传播该上下文,因此他的失败。 我认为这是一个不好的动机。 这些一致性失败是以下事实的直接结果:通常,这些中间件层无论如何都不可能做正确的事,因为最终要调用的底层系统原语无法提供适当的控制。 因此,失败并不是真正的考验。 我是显式参数系统提供的控件和非常清晰的语义的忠实粉丝。 对于使用隐式全局上下文的代码而言,很容易就根本无法考虑设计问题。
- 出于同样的原因,我确实发现Trio“护理”概念很有趣。 定义并发机制的大多数系统实质上将任何新的执行线程都视为在全局上下文中发生。 三重托儿所要求一项任务具有明确的范围。 当然,可以通过在全球苗圃中创建所有任务来滥用它,但是总体而言,他在分析中描述了许多有用的后果。
- 我也很喜欢边缘设计和水平触发设计之间的讨论链接。 我在“ 深度防御还是Hack? 在事件与基于状态的API的上下文中,这是另一个说法。
如果您对整个主题都感兴趣,那么我建议您更深入地研究上面的链接。
From: https://hackernoon.com/still-trying-to-get-control-c-right-d738b4de0b8a