Why do we need both std :: prom and std :: future?

I wonder why we need both std :: prom and std :: future? why is C ++ 11 standard splitting get and set_value into two separate classes std :: future and std :: prom? In response to this post, he mentioned that:

The reason it is divided into these two separate “interfaces” is to hide the “record / set” function from the “consumer / reader”.

I don’t understand how to hide here. But isn’t it easier if we have only one class of "future"? For example: replace.set_value can be replaced by future.set_value.

+8
c ++ c ++ 11
source share
2 answers

The problem that a promise / future exists is to pop a value from one thread to another. It may also throw an exception.

Thus, the source stream must have some object with which it can talk in order to send the desired value to another stream. Well ... who owns this object? If the source has a pointer to what belongs to the target stream, how does the source know if the target stream has deleted the target? Perhaps the destination stream no longer cares about cost; perhaps something has changed so that he just decided to throw his thread on the floor and forget about it.

This legal code is in some cases.

So, now the question is why the source does not own the promise and simply indicates the addressee a pointer / link to it? Well, there is a good reason for this: the promise belongs to the original thread. As soon as the source thread is completed, the promise will be destroyed. Thus, leaving the destination stream a reference to the destroyed promise.

Unfortunately.

Therefore, the only viable solution is to have two fully functional objects: one for the source and one for the destination. These objects share ownership of the transferred value. Of course, this does not mean that they cannot be of the same type; you could have something like shared_ptr<promise> or somesuch. After all, a promise / future should have some kind of shared repository of some kind inside, right?

However, consider the promise / future interface as they currently stand.

promise not copied . You can move it, but you cannot copy it. future also not copied, but future can become shared_future , which can be copied. This way you can have several destinations, but only one source.

promise can set value only; he can't even get it back. future can only get value; he cannot install it. Therefore, you have an asymmetric interface that is fully suitable for this use case. You do not want the destination to be able to set the value and source to get it. This is the reverse logic of the code.

So why do you need two objects. You have an asymmetric interface and is best handled by two related, but separate types and objects.

+19
source share

I would think of a promise / future as an asynchronous queue (which is intended only to hold a single value).

The future is the end of reading in line. A promise is the end of a queue record.

The use of the two usually differs: the producer usually just writes to the “queue”, and the consumption is simply read from it. Although, as you have already noted, you can read the value for the producer, there is rarely a reason for this, so optimizing this particular operation is rarely seen as a major part of priority.

In the usual scheme of things, the producer produces value and puts it in a promise. Consumer gets value from the future. Each "client" uses one simple interface designed exclusively for one simple task, therefore it is easier to create and document code, as well as to ensure that (for example) the consumer code does not bother with something related to the production of the value (or vice versa). Yes, it is possible, but enough additional work is unlikely to happen by accident.

+4
source share

All Articles