返回

文章详情

FoundationDB的Flow – 为C++11带来基于Actor的并发

Hacker News2026年7月2日 14:41

工程挑战 FoundationDB以每个节点高性能和可伸缩性为目标,开始了其开发过程。我们知道,要实现这些目标,我们在开发FoundationDB核心时将面临严重的工程挑战。我们需要实现高效的异步通信进程,这种进程类似于Erlang或.NET中的Async库,但我们也需要C++的原始速度和I/O效率。最后,我们还需要进行广泛的模拟,为大集群的可靠性和容错性进行工程设计。为应对这些挑战,我们开发了几个新工具,其中第一个是Flow,这是一种新编程语言,为C++11带来了基于Actor的并发。为了增加这种能力,Flow引入了一些新的关键字和控制流原语来管理并发。Flow作为一个编译器实现,它分析异步函数(Actor),并将其重写为一个具有多个不同子函数的对象,这些子函数使用回调来避免阻塞(请参见streamlinejs,它使用JavaScript实现类似的概念)。Flow编译器的输出是标准的C++11代码,随后使用传统工具编译为二进制文件。Flow还为我们的模拟工具提供输入,该工具对整个系统进行确定性模拟,包括其物理接口和故障模式。总之,Flow允许在C++中以可维护和可扩展的方式实现高效的并发,达成所有三个主要工程目标:高性能(通过编译为本机代码)、基于Actor的并发(以实现高生产力开发)、模拟支持(用于测试)。 初步了解 Flow中的Actor使用一种称为future的数据类型相互接收异步消息。当一个Actor需要一个数据值以继续计算时,它会在不阻塞其他Actor的情况下等待该值。以下是一个简单的Actor执行异步加法。它接受一个future整数和一个普通整数作为偏移量,等待future整数,并返回该值与偏移量的和: ACTOR Future < int > asyncAdd ( Future < int > f , int offset ) { int value = wait ( f ); return value + offset ; } Flow特性 Flow的新关键字和控制流原语支持异步在组件间传递消息的能力。以下是简要概述。 Promise<T>和Future<T> 连接异步发送者和接收者的数据类型是Promise<T>和Future<T>,其中T是某个C++类型。当发送者持有Promise<T>时,它代表着在未来某个时刻向持有Future<T>的对象传递类型T的值的承诺。相反,持有Future<T>的接收者可以异步继续计算,直到它实际需要T的时刻。Promise和future可以在单个进程内使用,但它们在分布式系统中的真正优势在于它们可以跨网络传递。例如,一台计算机可以创建一个promise/future对,然后通过网络将promise发送给另一台计算机。promise和future仍然是连接的,当promise被远程计算机兑现时,原来的future持有者将看到该值出现。 wait() 当持有Future<T>的接收者需要T以继续计算时,它会使用Future<T>作为参数调用wait()语句。wait()语句允许调用的Actor暂停执行,直到future的值被设置,返回类型为T的值。在等待期间,其他Actor可以继续执行,从而在单个进程内提供异步并发。 ACTOR 只有带有ACTOR标签的函数可以调用wait()。Actor是异步工作的基本单位,可以组合以创建复杂的消息传递系统。通过组合Actor,Futures可以链接在一起,使得一个的结果依赖于另一个的输出。一个Actor被声明为返回Future<T>,其中T可以是Void,如果Actor的返回值仅用于信号传递。每个Actor都会被预处理为一个具有内部回调和支持函数的C++11类。 状态 状态关键字用于限制变量的作用域,以便在一个Actor内多个wait()语句中可见。状态变量在下面的示例Actor中得到了说明。 PromiseStream<T>, FutureStream<T> 当一个组件想要处理一系列异步消息而不是单个消息时,可以使用PromiseStream<T>和FutureStream<T>。这些构造允许两个重要的特性:消息的复用和可靠传递。它们在Flow的设计模式中也扮演着重要角色。例如,FoundationDB中的许多服务器将其接口公开为一组promise流——每种请求类型一个。 waitNext() waitNext()是流的wait()的对应操作。它暂停程序执行,并等待FutureStream中的下一个值。如果流中有值准备好,执行会毫无延迟地继续。 choose … when

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡