如何反转 set_value() 和“停用”一个承诺?
我在这里有一个关于同步的问题。我有一个“编写者”线程,它在每次迭代时为承诺分配不同的值“p”。我需要“读取器”线程等待该值的shared_futures,然后处理它们,我的问题是如何使用 future/promise 来确保读取器线程在执行处理任务之前等待“p”的新更新每次迭代?非常感谢。
I have a total n00b question here on synchronization. I have a 'writer' thread which assigns a different value 'p' to a promise at each iteration. I need 'reader' threads which wait for shared_futures of this value and then process them, and my question is how do I use future/promise to ensure that the reader threads wait for a new update of 'p' before performing their processing task at each iteration? Many thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以通过将 Promise 分配给空白 Promise 来“重置”它。
更完整的示例:
但是,这种方法的一个问题是,两个线程之间的同步可能会导致编写器在读取器调用
之间多次调用
或promise::set_value()
future::get()future::get()
在重置 Promise 时被调用。这些问题可以小心地避免(例如,在调用之间进行适当的睡眠),但这将我们带入黑客和猜测的领域,而不是逻辑上正确的并发性。因此,尽管可以通过将 Promise 分配给新的 Promise 来重置 Promise,但这样做往往会引发更广泛的同步问题。
You can "reset" a promise by assigning it to a blank promise.
A more complete example:
A problem with this approach, however, is that synchronization between the two threads can cause the writer to call
promise::set_value()
more than once between the reader's calls tofuture::get()
, orfuture::get()
to be called while the promise is being reset. These problems can be avoided with care (e.g. with proper sleeping between calls), but this takes us into the realm of hacking and guesswork rather than logically correct concurrency.So although it's possible to reset a promise by assigning it to a fresh promise, doing so tends to raise broader synchronization issues.
promise
/future
对被设计为仅携带单个值(或异常)。要执行您所描述的操作,您可能需要采用不同的工具。如果您希望多个线程(您的读者)全部停止在一个公共点,您可以考虑使用
屏障
。A
promise
/future
pair is designed to carry only a single value (or exception.). To do what you're describing, you probably want to adopt a different tool.If you wish to have multiple threads (your readers) all stop at a common point, you might consider a
barrier
.以下代码演示了如何使用
future
和promise
实现生产者/消费者模式。有两个
promise
变量,由生产者线程和消费者线程使用。每个线程都会重置两个promise
变量之一并等待另一个。The following code demonstrates how the producer/consumer pattern can be implemented with
future
andpromise
.There are two
promise
variables, used by a producer and a consumer thread. Each thread resets one of the twopromise
variables and waits for the other one.这个答案支持 Jeff Wofford 给出的答案,马纳古和法比奥。
杰夫和法比奥的解决方案有效。但要澄清的是,解决方案中发生的情况是,所谓的承诺重置并不是按所说重置承诺,而只是将新的承诺分配到为承诺所做的空间分配中。在 Fabio 的解决方案中,此分配是在 main 的堆栈上进行的,而在 Jeff 的解决方案中,它是一个全局变量。在每次迭代中,新的 Promise 是一个完全不同的 Promise,并且具有新的共享状态,并且从前一个 Promise 检索到的任何 future 都不会引用这个新的共享状态。
因此,这些解决方案并不完全是重置,而是回收承诺。每次迭代都会发生新的共享状态分配和解除分配。
正如马纳古提到的,
它用作单次异步数据通信机制。
This answer is in support of, along with a tiny bit of clarification, the answers given by Jeff Wofford, Managu and Fabio.
Jeff's and Fabio's solutions work. But just to make it clear, what is happening in the solutions is that the so called reset of the promise is not resetting the promise per say, but just move assigning a new promise into the space allocation made for the promise. In Fabio's solution this allocation is made on the stack in main, and in Jeff's solution it is a global variable. In each iteration, the new promise is a completely different promise, and has a new shared state and any future retrieved from the previous promise is not referring to this new shared state.
So these solutions are not exactly resetting, but recycling the promise. New shared state allocation and de-allocation is happening in each iteration.
As mentioned by Managu,
It serves as a single shot asynchronous data communication mechanism.