使用异步 API 更改反应堆的状态而不需要手动同步是否安全?

发布于 2025-01-16 22:15:14 字数 1403 浏览 2 评论 0 原文

嘿,

我正在使用带有异步 API 的 gRPC。这需要基于 之类的类构建反应器ClientBidiReactorServerBidiReactor

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

问题

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

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

老实说,我对此有点困惑。在grpc示例此处和<一href="https://github.com/grpc/grpc/blob/master/examples/cpp/route_guide/route_guide_callback_client.cc#L232" rel="nofollow noreferrer">这里这似乎不是已解决(互斥锁有不同的用途,并且值不是原子的)。

我使用/链接了 Bidi 反应器的示例,但这指的是所有类型的反应器。

结论/问题

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

  • 这里的担忧是否有效,我是否正确理解了一切,或者我错过了什么?问题是否存在?
  • 我们是否需要手动同步反应堆的状态,或者它是否由库以某种方式处理(我的意思是刷新到已处理的主内存)?
  • 图书馆作者是否意识到这一点?他们在编写我链接的示例时是否记住了这一点?

预先感谢您的帮助,祝一切顺利!

Hey

I'm using gRPC with the async API. That requires constructing reactors based on classes like ClientBidiReactor or ServerBidiReactor

If I understand correctly, the gRPC works like this: It takes threads from some thread pool, and using these threads it executes certain methods of the reactors that are being used.

The problem

Now, the problem is when the reactors become stateful. I know that the methods of a single reactor will most probably be executed sequentially, but they may be run from different threads, is this correct? If so, then is it possible that we may encounter a problem described for instance here?

Long story short, if we have an unsynchronized state in such circumstances, is it possible that one thread will update the state, then a next method from the reactor will be executed from a different thread and it will see the not-updated value because the state's new value has not been flushed to the main memory yet?

Honestly, I'm a little confused about this. In the grpc examples here and here this doesn't seem to be addressed (the mutex is for a different purpose there and the values are not atomic).

I used/linked examples for the bidi reactors but this refers to all types of reactors.

Conclusion / questions

There are basically a couple of questions from me at this point:

  • Are the concerns valid here and do I properly understand everything or did I miss something? Does the problem exist?
  • Do we need to manually synchronize reactors' state or is it handled by the library somehow(I mean is flushing to the main memory handled)?
  • Are the library authors aware of this? Did they keep this in mind while they were coding examples I linked?

Thank you in advance for any help, all the best!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风为裳 2025-01-23 22:15:14

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

原始回调 API 规范在“线程安全”条款下对此做了更多说明:L67:基于C++回调的异步API。在回调实现代码本身的几个地方重申了同样的内容 - client_callback.h#L234-236

You're right that the examples don't showcase this very well, there's some room for improvement. The operation-completion reaction methods (OnReadInitialMetadataDone, OnReadDone, OnWriteDone, ...) can be called concurrently from different threads owned by the gRPC library, so if your code accesses any shared state, you'll want to coordinate that yourself (via synchronization, lock-free types, etc). In practice, I'm not sure how often it happens, or which callbacks are more likely to overlap.

The original callback API spec says a bit more about this, under a "Thread safety" clause: L67: C++ callback-based asynchronous API. The same is reiterated a few places in the callback implementation code itself - client_callback.h#L234-236 for example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文