cplusplus / concurrency-ts Goto Github PK
View Code? Open in Web Editor NEWThe draft C++ Library Concurrency Technical Specification
The draft C++ Library Concurrency Technical Specification
All output shared_future valid() == true.
must be
All input shared_future valid() == true.
[straw poll] LEWG prefers auto-unwrapping in .then() even though it’s inconsistent with async()?
SF F N A SA
2 4 5 0 0
As async returns a std::future and we are adding a std::experimental::future it seems to me that we need to add an async function in std::experimental that returns a std::experimental::future.
Maybe it is worth changing the semantics of async and return a future that doesn't block on destruction.
Two things here:
[Straw poll] Have the wording for when_any_swapped (perhaps named differently) allow implementations to reorder the array of futures, and put more than one ready future at the end?
SF F N A SA
4 4 1 0 0
[Straw poll] Should we use a different name from “when_any_swapped”?
SF F N A SA
5 3 0 0 0
The following paragraph is unclear
2.6.4
Header <serial_executor> synopsis
2 The number of add() calls on the underlying executor is unspecified, and if the underlying executor guarantees an ordering on its closures, that ordering won't necessarily extend to closures added through a serial_executor. [ Note: this is because serial_executor can batch add() calls to the underlying executor. — end note ]
I don't see how a serial executor can batch add() calls if it needs to preserve the sequence of task as specified in
1 ... If e.add(c1) happens before e.add(c2), then c1 is executed before c2.
IMO, the add() calls to the underlying executor must be synchronized with the end of execution of the previous submitted task.
Maybe some clarifications are needed.
Add a postcondition on the when_all/when_any
valid() == true
I would add the same kind of clarifications i have requested for is_ready #24 as the result is not stable.
The following doesn't seems to be an effect of the call to then()
The continuation is called when the object's shared state is ready (has a value or exception stored).
It is not this function that do this but the internal function that is called by the thread.
Postconditions:
The future object is moved to the parameter of the continuation function.
It is not clear to me what this means. The future will be moved to the shared state of the returned future and only when it becomes ready it will be moved on the call to the continuation.
It is not clear from the wording what the destructor could do.
The same applies to shared_future::then(), when_all() and when_any() functions.
The notes in
2.4 Class executor
10 Notes: If an executor is destroyed inside a closure running on that executor object, the behavior is undefined.
Should be transformed on a Require clause
The Effects clause states
Each future and shared_future is waited upon and then copied into the collection of the output (returned) future, maintaining the order of the futures in the input collection.
I don't think that the futures are waited in this function. IMO the future are moved and the shared_future is copied to the shared state of the new future.
It is only internal function used for the new created thread that will wait on all the futures/shared_futures.
Resuming this is not a blocking function.
in 2.4.11:
void executor::add(std::function closure);
2.4 Class executor 2
All closures are defined to execute on some thread, but which thread is largely unspecified.
++ Once the thread is chosen, the closure executes completely on this thread.
As such accessing a thread_local variable is defined behavior, though it is unspecified which thread's thread_local will be accessed.
Each header described in this technical specification shall import the contents of std::experimental::concurrency_v1 into std::experimental as if by
namespace std {
namespace experimental {
inline namespace concurrency_v1 {}
}
}
The following Require clause is no more needed as the parameter is a reference
In 2.6.4 Header <serial_executor> synopsis
4 Requires: underlying_executor shall not be null.
The latest round of edits removed all mentioning of shared_future
in the Effects clause:
If any of the
future
s supplied to a call to when_all ...
must be:
If any of the
future
s orshared_future
s supplied to a call to when_all ...
The continuation takes future as parameter
When result_of_t<decay_t<F>()>
is future<R>
, the function returns future<R>
.
Otherwise, the function returns future<result_of_t<decay_t<F>()>>
.
must be replaced with
When result_of_t<decay_t<F>(future<R>)>
is future<R2>
, the function returns future<R2>
.
Otherwise, the function returns future<result_of_t<decay_t<F>(future<R>)>>
.
valid()==true for the returned future.
This
auto f2 = f1.then([](future n) { return 2; });
should be
auto f2 = f1.then([](future<int> n) { return 2; });
Why unwrap has been removed? and when?
After removing the executor section the scheduler must be removed also.
template
see below when_all(InputIterator first, InputIterator last);
should be
template
see below when_all(InputIterator first, InputIterator last);
It is not clear when the result of when_all/when_any becomes ready.
I see two possibilities:
Boost.Thread implements option 2, but I suspect that only option 1 is correct.
Both when_all
/when_any
returns a future<tuple<>>
when there is no argument.
It seems to me that the variadic version should return future<tuple<Ts...>>
instead of a future<vector<T...>>
even when all T in Ts are the same.
Having a tuple helps to preserve the static information and would allow to pass a continuation that uses apply to call a function that has exactly the same types.
Compare
when_all(f1, f2).then([](future<tuple<future<int>, future<int>> f) {
return apply(fct, f.get());
}
to the more verbose
when_all(f1, f2).then([](future<vector<future<int>> f) {
vector<future<int> v = f.get();
return fct(v[0], v[1]);
}
So future<vector<F>>
will be reserved for the dynamic version having iterators as parameters, which seems coherent.
If the user prefers a dynamic version even when it has a static number of futures it could always push the futures on a vector and use the dynamic version.
It should specify the known exception that can be thrown.
Add the synopsis section for <experimental/future> file as in section 9 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4083.html.
<cxx-notes>
must only be used inside <cxx-function>
It is unspecified what happens with deferred tasks. A potential solution is proposed in N4032:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4032.html
It would be great if the specification make use of a typedef for function<void()>
.
This would allow to move in other version to a function wrapping class that can be initialized by moving the function.
Add a precondition to when_all/when_any/when_any_back
All input future<T>s valid() == true.
All input shared_future<T> valid() == true.
Calling the second signature of when_any with no arguments returns a future<tuple<>> that is immediately ready.
Replace the "The three functions " by These functions"
It seems to me that we must return future<vector<shared_future>> when the typename InputIterator::value_type is shared_future
I suggest to replace future<vector<future<R>>>
by future<vector<typename InputIterator::value_type>>
if the input cardinality is unknown at compile. typename InputIterator::value_type::value_type
may be void
. The order of the futures in the output vector will be the same as given by the input iterator.
Replace future<tuple<F0<R0>, F1<R1>, F2<R2>...>>
by future<tuple<T...>>
As there is not too much trouble with the result type, I suggest also to remove the see below.
template <class InputIterator>
future<vector<typename InputIterator::value_type>> when_all(InputIterator first, InputIterator last);
template <typename... T>
future<tuple<T...>> when_all(T&&... futures);
The same could be applied to when_any.
[straw poll] Prefer a longer, more descriptive name for thread_executor? (e.g. thread_per_closure_executor, but not necessarily that name)
SF F N A SA
4 3 2 0 0
In 2.6.2 Header <thread_pool> synopsis
4 Throws:
system_error if the threads can't be created and started.thread_pool::~thread_pool()
The thread_pool::~thread_pool() part seems to be a typo.
The use of sentence as "but in general such use is risky" is not justified. The standard should not include guidelines. If there is an issue the user must know which one it is.
2.4 Class executor
11 Notes ... but in general such use is risky
What is the result if the future is invalid? I guess it is false or does is_ready has as precondition that the future is valid.
In addition I will add a Remark to state clearly that the result of this function is not stable and that the future could become not ready even if the function returned true or vice-versa.
The original observation was made by Anthony Williams in N4032 regarding the explicit unwrap
, which is no longer part of the proposal. However, even without the explicit unwrap
we still have an issue. Consider the following code:
bool func();
void f()
{
future<int> f1 = async([]() { return 123; });
future<std::string> f2 = f1.then([](future<int> f) {
future<std::string> inner_valid = async([]() {
return std::string("fred");
});
future<std::string> inner_invalid;
future<std::string> result;
result = func() ? std::move(inner_valid) : std::move(inner_invalid);
return result; // implicit unwrap
});
auto v = f2.valid(); // valid or not?
}
It is not possible to determine if f2
should be valid or not before the functor passed into then
has completed. The proposal is to make the future valid, but if the inner future ends up as not valid, the outer future (f2
) becomes ready with an exception of type std::future_error
, with an error code of std::future_errc::broken_promise
.
It would be great if this section is coherent with the one from Fundamental TS.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4084.html#general.namespaces
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4083.html
Add
Remarks: These signatures shall not participate in overload resolution unless F is Callable with future.
The same applies to shared_future::then().
The Effects clause
The future returned by when_all will not throw an exception, but the futures held in the output collection may.
I would say
The future returned by when_all will not throw an exception when calling wait() or get(), but the futures held in the output collection may.
There are yet some "the third function" that should be replaced by "the second function" or the function with a launch parameter.
This is already implied in a few places, but need to make sure the semantics are clearly stated in the paper.
In 2.6.2 Header <thread_pool> synopsis
4 Throws:
system_error if the threads can't be created and started.
[Straw poll] Prefer is_X() over X() for predicate functions?
SF F N A SA
6 0 1 3 0
A big fat copy-paste mistake.
In in 3.2 Changes to class template future §10, it is not clear what it is returned by the function. The current description talks only about the type.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.