在没有手动同步的情况下使用异步 API 更改反应器的状态是否安全?

Is it safe to change the reactor's state using the async API without manual synchronization?

我将 gRPC 与异步 API 结合使用。这需要基于 类 构建反应堆,例如 ClientBidiReactor or ServerBidiReactor

如果我理解正确的话,gRPC 是这样工作的:它从某个线程池中获取线程,并使用这些线程执行正在使用的反应堆的某些方法。

问题

现在,问题是反应器何时变为有状态。我知道单个反应器的方法很可能会按顺序执行,但它们可能 运行 来自不同的线程,这是正确的吗?如果是这样,那么我们是否可能遇到描述的问题,例如 here?

长话短说,如果我们在这种情况下有一个不同步的状态,是否有可能一个线程会更新状态,然后来自反应堆的下一个方法将从另一个线程执行,它会看到不-updated value 因为状态的新值还没有刷新到主内存?

老实说,我对此有点困惑。在 grpc 示例中 here and here 这似乎没有得到解决(互斥体在那里用于不同的目的并且值不是原子的)。

我 used/linked 比迪反应器的示例,但这指的是所有类型的反应器。

结论/问题

此时我基本上有几个问题:

提前感谢您的帮助,祝一切顺利!

你是对的,这些例子并没有很好地展示这一点,还有一些改进的余地。 operation-completion 反应方法(OnReadInitialMetadataDoneOnReadDoneOnWriteDone、...)可以从 gRPC 库拥有的不同线程同时调用,因此如果您的代码访问任何共享状态,您需要自己协调(通过同步、lock-free 类型等)。实际上,我不确定它发生的频率,或者哪些回调更有可能重叠。

原始回调 API 规范在“线程安全”条款下对此做了更多说明:例如 L67: C++ callback-based asynchronous API. The same is reiterated a few places in the callback implementation code itself - client_callback.h#L234-236