Topic: Comments on N3785 - Executors and Schedulers
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 14 Jan 2014 00:29:55 +0100
Raw View
Hi,
I'm working on an implementation of Executors in Boost.Thread [1]
I'm taking a similar but different approach respect to N3785. Instead of=20
basing all the design on a abstract executor class, Executor is a concept.
I believe that this is the good direction as a static polymorphic=20
executor can be seen as a dynamic polymorphic executor using a simple=20
adaptor.
I believe also that it would make the library more usable, and more=20
convenient for users.
The major design decisions changes concerns deciding what a unit of work=20
is, how to manage with units of work and time related functions in a=20
polymorphic way.
The library provides Executors based on static and dynamic polymorphism.=20
The static polymorphism interface is intended to be used on contexts=20
that need to have the best performances. The dynamic polymorphism=20
interface has some advantage as described in N3785.
[heading Closure]
One especially important question is just what a closure is. This=20
library has a very simple answer: a closure is a Callable with no=20
parameters and returning void.
N3785 choose the more specific std::function<void()> and states that in=20
practice the implementation of a template based approach or another=20
approach is impractical. I think that the template based approach is=20
compatible with a dynamic one. The author of N3785 give some arguments=20
in favor of using function<void()> as a closure.
The first one is that a virtual function can not be a template. This is=20
true but it is also true that the executor interface can provide the=20
template functions that call to the virtual public functions. Another=20
reason they give is that "a template parameter would complicate the=20
interface without adding any real generality. In the end an executor=20
class is going to need some kind of type erasure to handle all the=20
different kinds of function objects with void() signature, and that=92s=20
exactly what std::function already does". I think that it is up to the=20
executor to manage with this implementation details, not to the user.
I share all the argument they give related to the void() interface of=20
the work unit. No issue here.
The third one is related to performance. They assert that "any mechanism=20
for storing closures on an executor=92s queue will have to use some form=20
of type erasure. There=92s no reason to believe that a custom closure=20
mechanism, written just for std::executor and used nowhere else within=20
the standard library, would be better in that respect than=20
std::function<void()>". I believe that the implementation can do better=20
that storing the closure on a std::function<void()>. e.g. the=20
implementation can use a queue intrusive node to store the Closure.
In addition std::function<void()> can not be constructed by moving the=20
Closure, so e.g. std::packaged_task could not be a Closure.
[heading Scheduled work]
The approach I have started to work on is quite different respect=20
scheduled work of the N3785 proposal. Instead of adding the scheduled=20
operations to a specific scheduled_executor polymorphic interface, I've=20
opted by adding two member template functions to a class=20
scheduled_executor that wraps an existing executor as the=20
serial_executor does. Every immediate closure is forwarded to the=20
wrapped executor and the timed closures are enqueued on a specific=20
queue. When the duration is elapsed the closure is forwarded to the=20
wrapped executor.
This has several the advantages:
* The scheduled operations are available for any executor.
* The template functions could accept any chrono time_point and duration=20
respectively as we are not working with virtual functions.
In order to manage with all the clocks, there are two alternatives:
* transform the add_at operation to a add_after operation and let a=20
single scheduled_executor manage with a single clock.
* have an instance of a scheduled_executor<Clock> for each Clock.
I've chosen the first of those options.
Note that I've not implemented this class yet.
[heading At thread entry]
It is common idiom to set some thread local variable at the beginning of=20
a thread. As Executors could instantiate threads internally these=20
Executors shall provide for the ability to call a user specific function=20
at thread entry on the executor constructor.
For executors that don't instantiate any thread an that would use the=20
current thread this function shall be called only for the thread calling=20
the `at_thread_entry ` member function.
[heading Current executor]
The library does not provision for the ability to get the current=20
executor, though having access to it could simplify a lot the user code.
The reason is that the user can always use a thread_local variable and=20
reset it using the `at_thread_entry ` member function.
thread_local current_executor_state_type current_executor_state;
executor* current_executor() { return=20
current_executor_state.current_executor(); }
basic_thread_pool pool(
// at_thread_entry
[](basic_thread_pool& pool) {
current_executor_state.set_current_executor(pool);
}
);
[heading Default executor]
I share some of the concerns of the C++ standard committee (introduction=20
of a new single shared resource, a singleton, could make it difficult to=20
make it portable to all the environments) and that this library doesn't=20
need to provide a default executor for the time been.
With the at thread entry, the user can define his default executor=20
himself and use the `at_thread_entry ` member function to set the=20
default constructor.
thread_local default_executor_state_type default_executor_state;
executor* default_executor() { return=20
default_executor_state.default_executor(); }
// in main
MyDefaultExecutor myDefaultExecutor(
// at_thread_entry
[](MyDefaultExecutor& ex) {
default_executor_state.set_default_executor(ex);
}
);
basic_thread_pool pool(
// at_thread_entry
[&myDefaultExecutor](basic_thread_pool& pool) {
default_executor_state.set_default_executor(myDefaultExecutor);
}
);
Comments welcome,
Vicente
[1]=20
https://github.com/boostorg/thread/tree/develop/include/boost/thread/execut=
ors
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Akira Takahashi <faithandbrave@gmail.com>
Date: Tue, 14 Jan 2014 17:00:24 +0900
Raw View
--089e0115f902b39d3204efe9950c
Content-Type: text/plain; charset=UTF-8
Hi Vicente,
I totally agree your design.
And I think need allocator option for `basic_thread_pool`.
`basic_thread_pool` use `vector` internally.
--
>>========================
Akira Takahashi
mailto:faithandbrave@gmail.com
site: http://sites.google.com/site/faithandbrave/about/en
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0115f902b39d3204efe9950c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Vicente,<div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><br></div><div class=3D"gmail_quote">I totally agree your design.</d=
iv><div class=3D"gmail_quote">And I think need allocator option for `basic_=
thread_pool`.</div>
<div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">`basic_thre=
ad_pool` use `vector` internally.</div><div><br></div>-- <br>>>=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>Akira=
Takahashi<br>mailto:<a href=3D"mailto:faithandbrave@gmail.com">faithandbra=
ve@gmail.com</a><br>
site:=C2=A0<a href=3D"http://sites.google.com/site/faithandbrave/about/en">=
http://sites.google.com/site/faithandbrave/about/en</a></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0115f902b39d3204efe9950c--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 03 Feb 2014 07:49:23 +0100
Raw View
Le 14/01/14 09:00, Akira Takahashi a =E9crit :
> Hi Vicente,
>
> I totally agree your design.
Great.
> And I think need allocator option for `basic_thread_pool`.
>
> `basic_thread_pool` use `vector` internally.
>
>
yes, this could be added without too much trouble.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Mon, 3 Feb 2014 16:32:25 +0100
Raw View
--f46d0438946d09d13f04f1823b5e
Content-Type: text/plain; charset=UTF-8
I don't have much to add, I think too that these changes appear good to me.
The parts about at_thread_entry seems to solve several problems I've had in
my attempt at having an Executor-like implementation.
Having closures as a concept would make easier to migrate my code for me
because I use a custom task type instead of std::function<>
to manage some special cases tasks which in the end gets pushed into an
Executor-like.
I would be happy to test your implementation in a real project because we
really need to try the concept approach to actually ckeck if
it's as problematic as the Executor paper suggests.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--f46d0438946d09d13f04f1823b5e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra">I don't have much to add, I=
think too that these changes appear good to me.</div><div class=3D"gmail_e=
xtra">The parts about at_thread_entry seems to solve several problems I'=
;ve had in my attempt at having an Executor-like implementation.<br>
</div><div class=3D"gmail_extra">Having closures as a concept would make ea=
sier to migrate my code for me because I use a custom task type instead of =
std::function<><br>to manage some special cases tasks which in the en=
d gets pushed into an Executor-like.</div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">I would be =
happy to test your implementation in a real project because we really need =
to try the concept approach to actually ckeck if=C2=A0</div><div class=3D"g=
mail_extra">
it's as problematic as the Executor paper suggests.<br></div><div class=
=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d0438946d09d13f04f1823b5e--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 06 Feb 2014 18:41:26 +0100
Raw View
Le 03/02/14 16:32, Klaim - Jo=EBl Lamotte a =E9crit :
> I don't have much to add, I think too that these changes appear good=20
> to me.
> The parts about at_thread_entry seems to solve several problems I've=20
> had in my attempt at having an Executor-like implementation.
> Having closures as a concept would make easier to migrate my code for=20
> me because I use a custom task type instead of std::function<>
> to manage some special cases tasks which in the end gets pushed into=20
> an Executor-like.
>
The single thing that should required for a Closure is to be a Callable=20
with void() signature (but I have only tested it with free functions for=20
the time been) :(.
> I would be happy to test your implementation in a real project because=20
> we really need to try the concept approach to actually ckeck if
> it's as problematic as the Executor paper suggests.
>
The current implementation is on Boost.Thread develop branch. I have=20
however some pending issues with async and on an example using=20
recursively async(ex, ...) (quick_sort) :(. I'm working yet on the=20
documentation and there are not too much examples (see [1], and [2]).
Please contact me directly if you have any issues.
Vicente
[1]=20
https://github.com/boostorg/thread/blob/develop/example/parallel_accumulate=
..cpp
[2] https://github.com/boostorg/thread/blob/develop/example/executor.cpp=20
or https://github.com/boostorg/thread/blob/develop/example/thread_pool.cpp
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 6 Feb 2014 18:59:46 +0100
Raw View
--089e013d0d6c8bd4a704f1c0a30e
Content-Type: text/plain; charset=UTF-8
On Thu, Feb 6, 2014 at 6:41 PM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:
> The current implementation is on Boost.Thread develop branch. I have
> however some pending issues with async and on an example using recursively
> async(ex, ...) (quick_sort) :(. I'm working yet on the documentation and
> there are not too much examples (see [1], and [2]).
>
> Please contact me directly if you have any issues.
>
Noted, I will be working on this around the end of next week and I'll
report later.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e013d0d6c8bd4a704f1c0a30e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Thu, Feb 6, 2014 at 6:41 PM, Vicente J. Botet Escriba <span dir=3D"ltr">=
<<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vicente.b=
otet@wanadoo.fr</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div id=3D":2l1" style=3D"overflow:hidden">T=
he current implementation is on Boost.Thread develop branch. I have however=
some pending issues with async and on an example using recursively async(e=
x, ...) (quick_sort) :(. I'm working yet on the documentation and there=
are not too much examples (see [1], and [2]).<br>
<br>
Please contact me directly if you have any issues.</div></blockquote></div>=
<br>Noted, I will be working on this around the end of next week and I'=
ll report later.</div><div class=3D"gmail_extra"><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e013d0d6c8bd4a704f1c0a30e--
.
Author: aleksey.vasenev@gmail.com
Date: Sat, 1 Nov 2014 11:12:57 -0700 (PDT)
Raw View
------=_Part_574_401829249.1414865577702
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I see current code and found some issues:
1. Executors destructor block until all task complete, but N3785 not=20
(except thread pool?).
2. Submit method work differently on different executors, some throw=20
exception and some silently ignore error (thread_executor and=20
inline_executor).
3. Task exceptions silently ignored. I think std::terminate solution from N=
3785 and=20
std::thread is better choice and more consistent.
4. BUG: In serial_executor we have infinite wait if task throw exception.
5. In N3785 ~thread_executor join threads but boost implementation simply=
=20
detach (potential use of deleted objects in tasks)
=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D1=8F=D0=BD=D0=B2=D0=B0=D1=
=80=D1=8F 2014 =D0=B3., 3:29:55 UTC+4 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=
=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Vicente J. Botet=20
Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> Hi,=20
>
> I'm working on an implementation of Executors in Boost.Thread [1]=20
>
> I'm taking a similar but different approach respect to N3785. Instead of=
=20
> basing all the design on a abstract executor class, Executor is a concept=
..=20
> I believe that this is the good direction as a static polymorphic=20
> executor can be seen as a dynamic polymorphic executor using a simple=20
> adaptor.=20
> I believe also that it would make the library more usable, and more=20
> convenient for users.=20
>
> The major design decisions changes concerns deciding what a unit of work=
=20
> is, how to manage with units of work and time related functions in a=20
> polymorphic way.=20
>
> The library provides Executors based on static and dynamic polymorphism.=
=20
> The static polymorphism interface is intended to be used on contexts=20
> that need to have the best performances. The dynamic polymorphism=20
> interface has some advantage as described in N3785.=20
>
> [heading Closure]=20
>
> One especially important question is just what a closure is. This=20
> library has a very simple answer: a closure is a Callable with no=20
> parameters and returning void.=20
>
> N3785 choose the more specific std::function<void()> and states that in=
=20
> practice the implementation of a template based approach or another=20
> approach is impractical. I think that the template based approach is=20
> compatible with a dynamic one. The author of N3785 give some arguments=20
> in favor of using function<void()> as a closure.=20
>
> The first one is that a virtual function can not be a template. This is=
=20
> true but it is also true that the executor interface can provide the=20
> template functions that call to the virtual public functions. Another=20
> reason they give is that "a template parameter would complicate the=20
> interface without adding any real generality. In the end an executor=20
> class is going to need some kind of type erasure to handle all the=20
> different kinds of function objects with void() signature, and that=C3=AF=
=C2=BF=C2=BDs=20
> exactly what std::function already does". I think that it is up to the=20
> executor to manage with this implementation details, not to the user.=20
>
> I share all the argument they give related to the void() interface of=20
> the work unit. No issue here.=20
>
> The third one is related to performance. They assert that "any mechanism=
=20
> for storing closures on an executor=C3=AF=C2=BF=C2=BDs queue will have to=
use some form=20
> of type erasure. There=C3=AF=C2=BF=C2=BDs no reason to believe that a cus=
tom closure=20
> mechanism, written just for std::executor and used nowhere else within=20
> the standard library, would be better in that respect than=20
> std::function<void()>". I believe that the implementation can do better=
=20
> that storing the closure on a std::function<void()>. e.g. the=20
> implementation can use a queue intrusive node to store the Closure.=20
>
> In addition std::function<void()> can not be constructed by moving the=20
> Closure, so e.g. std::packaged_task could not be a Closure.=20
>
> [heading Scheduled work]=20
>
> The approach I have started to work on is quite different respect=20
> scheduled work of the N3785 proposal. Instead of adding the scheduled=20
> operations to a specific scheduled_executor polymorphic interface, I've=
=20
> opted by adding two member template functions to a class=20
> scheduled_executor that wraps an existing executor as the=20
> serial_executor does. Every immediate closure is forwarded to the=20
> wrapped executor and the timed closures are enqueued on a specific=20
> queue. When the duration is elapsed the closure is forwarded to the=20
> wrapped executor.=20
>
> This has several the advantages:=20
>
> * The scheduled operations are available for any executor.=20
> * The template functions could accept any chrono time_point and duration=
=20
> respectively as we are not working with virtual functions.=20
>
> In order to manage with all the clocks, there are two alternatives:=20
> * transform the add_at operation to a add_after operation and let a=20
> single scheduled_executor manage with a single clock.=20
> * have an instance of a scheduled_executor<Clock> for each Clock.=20
>
> I've chosen the first of those options.=20
>
> Note that I've not implemented this class yet.=20
>
> [heading At thread entry]=20
>
> It is common idiom to set some thread local variable at the beginning of=
=20
> a thread. As Executors could instantiate threads internally these=20
> Executors shall provide for the ability to call a user specific function=
=20
> at thread entry on the executor constructor.=20
>
> For executors that don't instantiate any thread an that would use the=20
> current thread this function shall be called only for the thread calling=
=20
> the `at_thread_entry ` member function.=20
>
> [heading Current executor]=20
>
> The library does not provision for the ability to get the current=20
> executor, though having access to it could simplify a lot the user code.=
=20
> The reason is that the user can always use a thread_local variable and=20
> reset it using the `at_thread_entry ` member function.=20
>
> thread_local current_executor_state_type current_executor_state;=20
> executor* current_executor() { return=20
> current_executor_state.current_executor(); }=20
> basic_thread_pool pool(=20
> // at_thread_entry=20
> [](basic_thread_pool& pool) {=20
> current_executor_state.set_current_executor(pool);=20
> }=20
> );=20
>
> [heading Default executor]=20
>
> I share some of the concerns of the C++ standard committee (introduction=
=20
> of a new single shared resource, a singleton, could make it difficult to=
=20
> make it portable to all the environments) and that this library doesn't=
=20
> need to provide a default executor for the time been.=20
>
> With the at thread entry, the user can define his default executor=20
> himself and use the `at_thread_entry ` member function to set the=20
> default constructor.=20
>
> thread_local default_executor_state_type default_executor_state;=20
> executor* default_executor() { return=20
> default_executor_state.default_executor(); }=20
>
> // in main=20
> MyDefaultExecutor myDefaultExecutor(=20
> // at_thread_entry=20
> [](MyDefaultExecutor& ex) {=20
> default_executor_state.set_default_executor(ex);=20
> }=20
> );=20
>
> basic_thread_pool pool(=20
> // at_thread_entry=20
> [&myDefaultExecutor](basic_thread_pool& pool) {=20
> default_executor_state.set_default_executor(myDefaultExecutor);=20
> }=20
> );=20
>
>
> Comments welcome,=20
> Vicente=20
>
> [1]=20
>
> https://github.com/boostorg/thread/tree/develop/include/boost/thread/exec=
utors=20
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_574_401829249.1414865577702
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I see current code and found some issues:<div>1. Executors=
destructor block until all task complete, but N3785 not (except thread poo=
l?).</div><div>2. Submit method work differently on different executors, so=
me throw exception and some silently ignore error (thread_executor and inli=
ne_executor).</div><div>3. Task exceptions silently ignored. I think std::t=
erminate solution from <span style=3D"font-size: 13.1428575515747px;">=
N3785 and std::thread is better choice and more consistent.</span></di=
v><div>4. BUG: In serial_executor we have infinite wait if task throw =
exception.</div><div>5. In <span style=3D"font-size: 13.1428575515747p=
x;">N3785</span><span style=3D"font-size: 13.1428575515747px;"> </span=
><span style=3D"font-size: 13px;">~thread_executor join threads but boost i=
mplementation simply detach (potential use of deleted objects in tasks)</sp=
an></div><div><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 14 =D1=8F=D0=
=BD=D0=B2=D0=B0=D1=80=D1=8F 2014 =D0=B3., 3:29:55 UTC+4 =D0=BF=D0=BE=
=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Vicente J. Bot=
et Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;">Hi,
<br>
<br>I'm working on an implementation of Executors in Boost.Thread [1]
<br>
<br>I'm taking a similar but different approach respect to N3785. Instead o=
f=20
<br>basing all the design on a abstract executor class, Executor is a conce=
pt.
<br>I believe that this is the good direction as a static polymorphic=20
<br>executor can be seen as a dynamic polymorphic executor using a simple=
=20
<br>adaptor.
<br>I believe also that it would make the library more usable, and more=20
<br>convenient for users.
<br>
<br>The major design decisions changes concerns deciding what a unit of wor=
k=20
<br>is, how to manage with units of work and time related functions in a=20
<br>polymorphic way.
<br>
<br>The library provides Executors based on static and dynamic polymorphism=
..=20
<br>The static polymorphism interface is intended to be used on contexts=20
<br>that need to have the best performances. The dynamic polymorphism=20
<br>interface has some advantage as described in N3785.
<br>
<br>[heading Closure]
<br>
<br>One especially important question is just what a closure is. This=20
<br>library has a very simple answer: a closure is a Callable with no=20
<br>parameters and returning void.
<br>
<br>N3785 choose the more specific std::function<void()> and states t=
hat in=20
<br>practice the implementation of a template based approach or another=20
<br>approach is impractical. I think that the template based approach is=20
<br>compatible with a dynamic one. The author of N3785 give some arguments=
=20
<br>in favor of using function<void()> as a closure.
<br>
<br>The first one is that a virtual function can not be a template. This is=
=20
<br>true but it is also true that the executor interface can provide the=20
<br>template functions that call to the virtual public functions. Another=
=20
<br>reason they give is that "a template parameter would complicate the=20
<br>interface without adding any real generality. In the end an executor=20
<br>class is going to need some kind of type erasure to handle all the=20
<br>different kinds of function objects with void() signature, and that=C3=
=AF=C2=BF=C2=BDs=20
<br>exactly what std::function already does". I think that it is up to the=
=20
<br>executor to manage with this implementation details, not to the user.
<br>
<br>I share all the argument they give related to the void() interface of=
=20
<br>the work unit. No issue here.
<br>
<br>The third one is related to performance. They assert that "any mechanis=
m=20
<br>for storing closures on an executor=C3=AF=C2=BF=C2=BDs queue will have =
to use some form=20
<br>of type erasure. There=C3=AF=C2=BF=C2=BDs no reason to believe that a c=
ustom closure=20
<br>mechanism, written just for std::executor and used nowhere else within=
=20
<br>the standard library, would be better in that respect than=20
<br>std::function<void()>". I believe that the implementation can do =
better=20
<br>that storing the closure on a std::function<void()>. e.g. the=20
<br>implementation can use a queue intrusive node to store the Closure.
<br>
<br>In addition std::function<void()> can not be constructed by movin=
g the=20
<br>Closure, so e.g. std::packaged_task could not be a Closure.
<br>
<br>[heading Scheduled work]
<br>
<br>The approach I have started to work on is quite different respect=20
<br>scheduled work of the N3785 proposal. Instead of adding the scheduled=
=20
<br>operations to a specific scheduled_executor polymorphic interface, I've=
=20
<br>opted by adding two member template functions to a class=20
<br>scheduled_executor that wraps an existing executor as the=20
<br>serial_executor does. Every immediate closure is forwarded to the=20
<br>wrapped executor and the timed closures are enqueued on a specific=20
<br>queue. When the duration is elapsed the closure is forwarded to the=20
<br>wrapped executor.
<br>
<br>This has several the advantages:
<br>
<br>* The scheduled operations are available for any executor.
<br>* The template functions could accept any chrono time_point and duratio=
n=20
<br>respectively as we are not working with virtual functions.
<br>
<br>In order to manage with all the clocks, there are two alternatives:
<br>* transform the add_at operation to a add_after operation and let a=20
<br>single scheduled_executor manage with a single clock.
<br>* have an instance of a scheduled_executor<Clock> for each Clock.
<br>
<br>I've chosen the first of those options.
<br>
<br>Note that I've not implemented this class yet.
<br>
<br>[heading At thread entry]
<br>
<br>It is common idiom to set some thread local variable at the beginning o=
f=20
<br>a thread. As Executors could instantiate threads internally these=20
<br>Executors shall provide for the ability to call a user specific functio=
n=20
<br>at thread entry on the executor constructor.
<br>
<br>For executors that don't instantiate any thread an that would use the=
=20
<br>current thread this function shall be called only for the thread callin=
g=20
<br>the `at_thread_entry ` member function.
<br>
<br>[heading Current executor]
<br>
<br>The library does not provision for the ability to get the current=20
<br>executor, though having access to it could simplify a lot the user code=
..
<br>The reason is that the user can always use a thread_local variable and=
=20
<br>reset it using the `at_thread_entry ` member function.
<br>
<br>thread_local current_executor_state_type current_executor_state;
<br>executor* current_executor() { return=20
<br>current_executor_state.<wbr>current_executor(); }
<br>basic_thread_pool pool(
<br>// at_thread_entry
<br>[](basic_thread_pool& pool) {
<br>current_executor_state.set_<wbr>current_executor(pool);
<br>}
<br>);
<br>
<br>[heading Default executor]
<br>
<br>I share some of the concerns of the C++ standard committee (introductio=
n=20
<br>of a new single shared resource, a singleton, could make it difficult t=
o=20
<br>make it portable to all the environments) and that this library doesn't=
=20
<br>need to provide a default executor for the time been.
<br>
<br>With the at thread entry, the user can define his default executor=20
<br>himself and use the `at_thread_entry ` member function to set the=20
<br>default constructor.
<br>
<br>thread_local default_executor_state_type default_executor_state;
<br>executor* default_executor() { return=20
<br>default_executor_state.<wbr>default_executor(); }
<br>
<br>// in main
<br>MyDefaultExecutor myDefaultExecutor(
<br>// at_thread_entry
<br>[](MyDefaultExecutor& ex) {
<br>default_executor_state.set_<wbr>default_executor(ex);
<br>}
<br>);
<br>
<br>basic_thread_pool pool(
<br>// at_thread_entry
<br>[&myDefaultExecutor](basic_<wbr>thread_pool& pool) {
<br>default_executor_state.set_<wbr>default_executor(<wbr>myDefaultExecutor=
);
<br>}
<br>);
<br>
<br>
<br>Comments welcome,
<br>Vicente
<br>
<br>[1]=20
<br><a href=3D"https://github.com/boostorg/thread/tree/develop/include/boos=
t/thread/executors" target=3D"_blank" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fboostorg%2Fthread%2Ftree%2=
Fdevelop%2Finclude%2Fboost%2Fthread%2Fexecutors\46sa\75D\46sntz\0751\46usg\=
75AFQjCNFQ6vHlEgypunhKec4l_ZQ9YbXVUw';return true;" onclick=3D"this.href=3D=
'https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fboostorg%2Fthrea=
d%2Ftree%2Fdevelop%2Finclude%2Fboost%2Fthread%2Fexecutors\46sa\75D\46sntz\0=
751\46usg\75AFQjCNFQ6vHlEgypunhKec4l_ZQ9YbXVUw';return true;">https://githu=
b.com/boostorg/<wbr>thread/tree/develop/include/<wbr>boost/thread/executors=
</a>
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_574_401829249.1414865577702--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 02 Nov 2014 01:56:42 +0100
Raw View
This is a multi-part message in MIME format.
--------------010902060704020400050201
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 01/11/14 19:12, aleksey.vasenev@gmail.com a =C3=A9crit :
> I see current code and found some issues:
> 1. Executors destructor block until all task complete, but N3785 not=20
> (except thread pool?).
thread_executor waits also in N3785.
serial_executor waits also in N3785 and.in Boost.Thread.
loop_executor, inline_executor don't wait, neither in N3785 nor in=20
Boost.thread.
> 2. Submit method work differently on different executors, some throw=20
> exception and some silently ignore error (thread_executor and=20
> inline_executor).
I will fix for inline_executor. Which error are ignored by=20
thread_executor::submit?
> 3. Task exceptions silently ignored. I think std::terminate solution=20
> from N3785 and std::thread is better choice and more consistent.
I will fix this also.
> 4. BUG: In serial_executor we have infinite wait if task throw exception.
Wouldn't the not caught exception terminate the program?
Anyway, I will add a try-catch-terminate.
> 5. In N3785~thread_executor join threads but boost implementation=20
> simply detach (potential use of deleted objects in tasks)
>
I will fix this also.
Thanks for reporting all these issues, I have created 5 Trac Tickets.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------010902060704020400050201
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 01/11/14 19:12,
<a class=3D"moz-txt-link-abbreviated" href=3D"mailto:aleksey.vasenev@=
gmail.com">aleksey.vasenev@gmail.com</a> a =C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:2ea1ee2c-6578-401b-a2d0-88b7ef59b0f7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">I see current code and found some issues:
<div>1. Executors destructor block until all task complete, but
N3785 not (except thread pool?).</div>
</div>
</blockquote>
thread_executor waits also in N3785.<br>
serial_executor waits also in N3785 and.in Boost.Thread.<br>
loop_executor, inline_executor don't wait, neither in N3785 nor in
Boost.thread.<br>
<br>
<blockquote
cite=3D"mid:2ea1ee2c-6578-401b-a2d0-88b7ef59b0f7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>2. Submit method work differently on different executors,
some throw exception and some silently ignore error
(thread_executor and inline_executor).</div>
</div>
</blockquote>
I will fix for inline_executor. Which error are ignored by
thread_executor::submit?
<blockquote
cite=3D"mid:2ea1ee2c-6578-401b-a2d0-88b7ef59b0f7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>3. Task exceptions silently ignored. I think std::terminate
solution from=C2=A0<span style=3D"font-size: 13.1428575515747px;"=
>N3785=C2=A0and
std::thread is better choice and more consistent.</span></div>
</div>
</blockquote>
I will fix this also.
<blockquote
cite=3D"mid:2ea1ee2c-6578-401b-a2d0-88b7ef59b0f7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>4. BUG: In=C2=A0serial_executor we have infinite wait if task
throw exception.</div>
</div>
</blockquote>
Wouldn't the not caught exception terminate the program?<br>
Anyway, I will add a try-catch-terminate.<br>
<blockquote
cite=3D"mid:2ea1ee2c-6578-401b-a2d0-88b7ef59b0f7@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>5. In=C2=A0<span style=3D"font-size: 13.1428575515747px;">N378=
5</span><span
style=3D"font-size: 13.1428575515747px;">=C2=A0</span><span
style=3D"font-size: 13px;">~thread_executor join threads but
boost implementation simply detach (potential use of deleted
objects in tasks)</span></div>
<div><br>
</div>
</div>
</blockquote>
I will fix this also.<br>
<br>
Thanks for reporting all these issues, I have created 5 Trac
Tickets. <br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------010902060704020400050201--
.
Author: aleksey.vasenev@gmail.com
Date: Sat, 1 Nov 2014 23:44:37 -0700 (PDT)
Raw View
------=_Part_882_2054089141.1414910677595
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=BD=D1=8C=D0=B5, 2 =D0=
=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F 2014 =D0=B3., 3:56:45 UTC+3 =D0=BF=D0=BE=
=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Vicente J. Bot=
et=20
Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> thread_executor waits also in N3785.
> serial_executor waits also in N3785 and.in Boost.Thread.
> loop_executor, inline_executor don't wait, neither in N3785 nor in=20
> Boost.thread.
>
Boost implementation wait active and pending tasks to complete.
But N3785:
~serial_executor Finishes running any currently executing closure, then=20
destroys all remaining closures and returns.
~loop_executor Any closures that haven=E2=80=99t been executed by a=20
closure-executing method when the destructor runs will never be executed.
~thread_pool Waits for closures (if any) to complete, then joins and=20
destroys the threads.
This proposal takes a simple approach to executor shutdown, generally just=
=20
dropping closures that haven't started yet. Java's Executor library, on the=
=20
other hand, provides a flexible mechanism for users to shut down executors=
=20
with control over how closures complete after shutdown has started. C++=20
should consider what's appropriate in this area. It should be noted,=20
though, that many of the common use cases for executors are such that=20
executor lifetime matches the lifetime of the application. The use cases=20
for controlled shutdown are more specialized and are often executor=20
specific, so adding complex shutdown semantics is currently left to=20
specific implementations of the executor interface.
Thread pool must complete all tasks or active tasks? I'm not sure. I think=
=20
second, because we can wrap any executor in serial_executor and behavior=20
must be identical.
> I will fix for inline_executor. Which error are ignored by=20
> thread_executor::submit?
>
Both thread_executor and inline_executor just return if closed, but another=
=20
throw exception from sync_queue::push_back.
I think we need throw exception or add assert for incorrect library usage.=
=20
I prefer first because on some platforms exceptions is zero-cost if not=20
throw and program correctly better than speed.
Also executors has common interface and therefore submit method behavior=20
must be common.=20
> Wouldn't the not caught exception terminate the program?
> Anyway, I will add a try-catch-terminate.
>
We run our task on another executor that silently ignore errors=20
in try_executing_one method.
If task throw exception, try_executing_one_task expect program to=20
terminate, but try_executing_one method return false.
We need either try{...} catch(...) {p.set_value(); throw;} to avoid=20
infinite wait, or fix all try_executing_one methods to bypass exceptions.
Second idea is bad because user can write custom executor or wrapper with=
=20
special exception handling (ignoring exceptions or write log for example).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_882_2054089141.1414910677595
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">=D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=BD=D1=
=8C=D0=B5, 2 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F 2014 =D0=B3., 3:56:4=
5 UTC+3 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=
=D1=8C Vicente J. Botet Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>thread_executor waits also in N3785.<br></div>
serial_executor waits also in N3785 <a href=3D"http://and.in" target=3D=
"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%=
2F%2Fand.in\46sa\75D\46sntz\0751\46usg\75AFQjCNHo0ZLeUSR5EPZ4hXLe4X5fXVbsgw=
';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fand.in\46sa\75D\46sntz\0751\46usg\75AFQjCNHo0ZLeUSR5EPZ4hXLe4X5fXVb=
sgw';return true;">and.in</a> Boost.Thread.<br>
loop_executor, inline_executor don't wait, neither in N3785 nor in
Boost.thread.<br></div></blockquote><div>Boost implementation wait acti=
ve and pending tasks to complete.</div><div>But N3785:</div><div>~serial_ex=
ecutor Finishes running any currently executing closure, then destroys all =
remaining closures and returns.</div><div>~loop_executor Any closures that =
haven=E2=80=99t been executed by a closure-executing method when the destru=
ctor runs will never be executed.</div><div>~thread_pool Waits for closures=
(if any) to complete, then joins and destroys the threads.</div><div><div>=
This proposal takes a simple approach to executor shutdown, generally just =
dropping closures that haven't started yet. Java's Executor library, on the=
other hand, provides a flexible mechanism for users to shut down executors=
with control over how closures complete after shutdown has started. C++ sh=
ould consider what's appropriate in this area. It should be noted, though, =
that many of the common use cases for executors are such that executor life=
time matches the lifetime of the application. The use cases for controlled =
shutdown are more specialized and are often executor specific, so adding co=
mplex shutdown semantics is currently left to specific implementations of t=
he executor interface.</div></div><div><br></div><div>Thread pool must comp=
lete all tasks or active tasks? I'm not sure. I think second, because we ca=
n wrap any executor in serial_executor and behavior must be identical.</div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=
=3D"#000000">
I will fix for inline_executor. Which error are ignored by
thread_executor::submit?</div></blockquote><div>Both thread_executor an=
d inline_executor just return if closed, but another throw exception from&n=
bsp;sync_queue::push_back.</div><div>I think we need throw exception or add=
assert for incorrect library usage. I prefer first because on some platfor=
ms exceptions is zero-cost if not throw and program correctly better than s=
peed.</div><div>Also executors has common interface and therefore submit me=
thod behavior must be common. </div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
Wouldn't the not caught exception terminate the program?<br>
Anyway, I will add a try-catch-terminate.<br></div></blockquote><div>We=
run our task on another executor that silently ignore errors in try_e=
xecuting_one method.</div><div>If task throw exception, try_executing_one_t=
ask expect program to terminate, but try_executing_one method return false.=
</div><div>We need either try{...} catch(...) {p.set_value(); throw;} to av=
oid infinite wait, or fix all try_executing_one methods to bypass exception=
s.</div><div>Second idea is bad because user can write custom executor or w=
rapper with special exception handling (ignoring exceptions or write log fo=
r example).</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_882_2054089141.1414910677595--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 02 Nov 2014 15:19:40 +0100
Raw View
This is a multi-part message in MIME format.
--------------050400080401000007030604
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 02/11/14 07:44, aleksey.vasenev@gmail.com a =C3=A9crit :
> =D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=BD=D1=8C=D0=B5, 2 =D0=
=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F 2014 =D0=B3., 3:56:45 UTC+3 =D0=BF=D0=BE=
=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Vicente J.=20
> Botet Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> thread_executor waits also in N3785.
> serial_executor waits also in N3785 and.in <http://and.in>
> Boost.Thread.
> loop_executor, inline_executor don't wait, neither in N3785 nor in
> Boost.thread.
>
> Boost implementation wait active and pending tasks to complete.
> But N3785:
> ~serial_executor Finishes running any currently executing closure,=20
> then destroys all remaining closures and returns.
> ~loop_executor Any closures that haven=E2=80=99t been executed by a=20
> closure-executing method when the destructor runs will never be executed.
> ~thread_pool Waits for closures (if any) to complete, then joins and=20
> destroys the threads.
The Boost.Thread implementation has no pending task, all are active.
> This proposal takes a simple approach to executor shutdown, generally=20
> just dropping closures that haven't started yet. Java's Executor=20
> library, on the other hand, provides a flexible mechanism for users to=20
> shut down executors with control over how closures complete after=20
> shutdown has started. C++ should consider what's appropriate in this=20
> area. It should be noted, though, that many of the common use cases=20
> for executors are such that executor lifetime matches the lifetime of=20
> the application. The use cases for controlled shutdown are more=20
> specialized and are often executor specific, so adding complex=20
> shutdown semantics is currently left to specific implementations of=20
> the executor interface.
>
> Thread pool must complete all tasks or active tasks? I'm not sure. I=20
> think second, because we can wrap any executor in serial_executor and=20
> behavior must be identical.
Right
>
> I will fix for inline_executor. Which error are ignored by
> thread_executor::submit?
>
> Both thread_executor and inline_executor just return if closed, but=20
> another throw exception from sync_queue::push_back.
I will fix this. I will throw if closed.
> I think we need throw exception or add assert for incorrect library=20
> usage. I prefer first because on some platforms exceptions is=20
> zero-cost if not throw and program correctly better than speed.
> Also executors has common interface and therefore submit method=20
> behavior must be common.
>
> Wouldn't the not caught exception terminate the program?
> Anyway, I will add a try-catch-terminate.
>
> We run our task on another executor that silently ignore errors=20
> in try_executing_one method.
> If task throw exception, try_executing_one_task expect program to=20
> terminate, but try_executing_one method return false.
> We need either try{...} catch(...) {p.set_value(); throw;} to avoid=20
> infinite wait, or fix all try_executing_one methods to bypass exceptions.
> Second idea is bad because user can write custom executor or wrapper=20
> with special exception handling (ignoring exceptions or write log for=20
> example).
>
IIUC, the try_executing_one_task issue is only one if the nested=20
executor ignore the exceptions. But this is a bug on the nested=20
executor, isnt it?
I have updated the code on branch scheduled_executors. See in particular
Fix task exception silently ignored. Make submit throw if closed. joi=E2=80=
=A6 -
https://github.com/boostorg/thread/commit/c1925df81c996f3fffd95e36f3b359916=
90a0787
Added not_ready and timeout queue_op_status. Make sync_timed_queue and=20
sync_priority_queue conform to the sync_queue interface. Adapt the tests=20
to the new interface.
https://github.com/boostorg/thread/commit/4f01891da7c0091aff0e34f3426eeb8c0=
24a3f6a
Please, be free to follow this discussion on github or contact myself=20
directly, as I don't think this is the correct ML to discuss=20
Boost.Thread issues.
Thanks again,
Vicente
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------050400080401000007030604
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 02/11/14 07:44,
<a class=3D"moz-txt-link-abbreviated" href=3D"mailto:aleksey.vasenev@=
gmail.com">aleksey.vasenev@gmail.com</a> a =C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:aacdc50e-a7a2-4062-a696-49d437ba8ab5@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">=D0=B2=D0=BE=D1=81=D0=BA=D1=80=D0=B5=D1=81=D0=B5=D0=
=BD=D1=8C=D0=B5, 2 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F 2014=C2=A0=D0=B3., =
3:56:45 UTC+3
=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=
=D1=8C Vicente J. Botet Escriba =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>thread_executor waits also in N3785.<br>
</div>
serial_executor waits also in N3785 <a
moz-do-not-send=3D"true" href=3D"http://and.in"
target=3D"_blank"
onmousedown=3D"this.href=3D'http://www.google.com/url?q\75htt=
p%3A%2F%2Fand.in\46sa\75D\46sntz\0751\46usg\75AFQjCNHo0ZLeUSR5EPZ4hXLe4X5fX=
Vbsgw';return
true;"
onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A=
%2F%2Fand.in\46sa\75D\46sntz\0751\46usg\75AFQjCNHo0ZLeUSR5EPZ4hXLe4X5fXVbsg=
w';return
true;">and.in</a> Boost.Thread.<br>
loop_executor, inline_executor don't wait, neither in N3785
nor in Boost.thread.<br>
</div>
</blockquote>
<div>Boost implementation wait active and pending tasks to
complete.</div>
<div>But N3785:</div>
<div>~serial_executor Finishes running any currently executing
closure, then destroys all remaining closures and returns.</div>
<div>~loop_executor Any closures that haven=E2=80=99t been executed=
by a
closure-executing method when the destructor runs will never
be executed.</div>
<div>~thread_pool Waits for closures (if any) to complete, then
joins and destroys the threads.</div>
</div>
</blockquote>
The Boost.Thread implementation has no pending task, all are active.<br=
>
<blockquote
cite=3D"mid:aacdc50e-a7a2-4062-a696-49d437ba8ab5@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>
<div>This proposal takes a simple approach to executor
shutdown, generally just dropping closures that haven't
started yet. Java's Executor library, on the other hand,
provides a flexible mechanism for users to shut down
executors with control over how closures complete after
shutdown has started. C++ should consider what's appropriate
in this area. It should be noted, though, that many of the
common use cases for executors are such that executor
lifetime matches the lifetime of the application. The use
cases for controlled shutdown are more specialized and are
often executor specific, so adding complex shutdown
semantics is currently left to specific implementations of
the executor interface.</div>
</div>
<div><br>
</div>
<div>Thread pool must complete all tasks or active tasks? I'm
not sure. I think second, because we can wrap any executor in
serial_executor and behavior must be identical.</div>
</div>
</blockquote>
Right<br>
<blockquote
cite=3D"mid:aacdc50e-a7a2-4062-a696-49d437ba8ab5@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000"> I will fix for
inline_executor. Which error are ignored by
thread_executor::submit?</div>
</blockquote>
<div>Both thread_executor and inline_executor just return if
closed, but another throw exception
from=C2=A0sync_queue::push_back.</div>
</div>
</blockquote>
I will fix this. I will throw if closed.<br>
<blockquote
cite=3D"mid:aacdc50e-a7a2-4062-a696-49d437ba8ab5@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>I think we need throw exception or add assert for incorrect
library usage. I prefer first because on some platforms
exceptions is zero-cost if not throw and program correctly
better than speed.</div>
<div>Also executors has common interface and therefore submit
method behavior must be common.=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000"> Wouldn't the not caugh=
t
exception terminate the program?<br>
Anyway, I will add a try-catch-terminate.<br>
</div>
</blockquote>
<div>We run our task on another executor that silently ignore
errors in=C2=A0try_executing_one method.</div>
<div>If task throw exception, try_executing_one_task expect
program to terminate, but try_executing_one method return
false.</div>
<div>We need either try{...} catch(...) {p.set_value(); throw;}
to avoid infinite wait, or fix all try_executing_one methods
to bypass exceptions.</div>
<div>Second idea is bad because user can write custom executor
or wrapper with special exception handling (ignoring
exceptions or write log for example).</div>
</div>
<br>
</blockquote>
IIUC, the try_executing_one_task issue is only one if the nested
executor ignore the exceptions. But this is a bug on the nested
executor, isnt it?<br>
<br>
<br>
I have updated the code on branch scheduled_executors. See in
particular<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF-8=
">
<p class=3D"commit-title"> Fix task exception silently ignored. Make
submit throw if closed. joi=E2=80=A6 -<br>
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/boostorg/thre=
ad/commit/c1925df81c996f3fffd95e36f3b35991690a0787">https://github.com/boos=
torg/thread/commit/c1925df81c996f3fffd95e36f3b35991690a0787</a><br>
</p>
<p class=3D"commit-title">
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF=
-8">
</p>
<p class=3D"commit-title"> Added not_ready and timeout
queue_op_status. Make sync_timed_queue and sync_priority_queue
conform to the sync_queue interface. Adapt the tests to the new
interface.<br>
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/boostorg/thre=
ad/commit/4f01891da7c0091aff0e34f3426eeb8c024a3f6a">https://github.com/boos=
torg/thread/commit/4f01891da7c0091aff0e34f3426eeb8c024a3f6a</a><br>
</p>
<p class=3D"commit-title">Please, be free to follow this discussion on
github or contact myself directly, as I don't think this is the
correct ML to discuss Boost.Thread issues.<br>
</p>
<p class=3D"commit-title">Thanks again,<br>
Vicente<br>
</p>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--------------050400080401000007030604--
.