Boost logo

Boost :

Subject: Re: [boost] [thread_pool] Dependencies between tasks
From: k-oli_at_[hidden]
Date: 2008-09-10 06:20:27


Hello Vicente,
I've uploaded a new version of threadpool wich incorporates your suggestions
regarding to chained_submit.

http://www.boostpro.com/vault/index.php?action=downloadfile&filename=boost-threadpool.4.tar.gz&directory=Concurrent%20Programming&

regards,
Oliver

Am Samstag, 6. September 2008 15:02:28 schrieb vicente.botet:
> ----- Original Message -----
> From: <k-oli_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Saturday, September 06, 2008 8:39 AM
> Subject: Re: [boost] [thread_pool] Dependencies between tasks
>
> > Am Samstag, 6. September 2008 06:40:03 schrieb vicente.botet:
> >> ----- Original Message -----
> >> From: "Kowalke Oliver (QD IT PA SI)" <Oliver.Kowalke_at_[hidden]>
> >> To: <boost_at_[hidden]>
> >> Sent: Friday, September 05, 2008 8:46 AM
> >> Subject: Re: [boost] [thread_pool] Dependencies between tasks
> >>
> >> > sequencing the access to the instance would be equivalent to chaining
> >> > the
> >> > tasks (== chained tasks are executed after each other -> as a
> >> > sequence).
> >> > take a look at thread_pool at the vault
> >> > http://www.boostpro.com/vault/index.php?action=downloadfile&filename=b
> >> >oos t-threadpool.2.tar.gz&directory=Concurrent%20Programming&.
> >>
> >> Do you mean that each time the user wants to sequence tasks she/he needs
> >> * chain the task to the stored one
> >> * store the last task
> >
> > I don't know what you mean with store a task.
>
> Well, in order to chain a task a need to have a reference to the task. This
> is what I meant by store a task.
>
> > signature of chained_submit:
> >
> > template<
> > typename Act,
> > typename T
> >
> > task< typename result_of< Act() >::type > chained_submit(
> > Act const& act,
> > task< T > & t);
> >
> > The function object act which should be passed to the thread pool is
> > chained
> > to the task t. This means - the function object act will be executed by I
> > worker thread if the task t was finished.
>
> OK, this allows us to chain tasks. Is this function thread_safe?
>
> > struct A
> > {
> > void f( std::string const& str)
> > { printf("A::f(): %s\n", str.c_str() ); }
> > };
> >
> > struct B
> > {
> > void g()
> > { printf("B::g()\n"); }
> > };
> >
> > A a;
> > B b;
> >
> > tp::pool<
> > tp::fixed,
> > tp::unbounded_channel< tp::fifo >
> >
> > > pool( tp::max_poolsize( 5) );
> >
> > tp::task< void > t1(
> > pool.submit(
> > boost::bind(
> > & A::f,
> > a,
> > "abc",
> > 2) ) );
> > tp::task< void > t2(
> > pool.chained_submit(
> > boost::bind(
> > & A::f,
> > a,
> > "efg",
> > 1),
> > t1) );
> > tp::task< void > t3(
> > pool.chained_submit(
> > boost::bind(
> > & A::f,
> > a,
> > "hij",
> > 0),
> > t2) );
> >
> > pool.submit(
> > boost::bind(
> > & B::g,
> > b) );
> >
> > t3.get_future().wait();
>
> This works well as soon as we have a reference to the task t1 when we
> submit the task t2, and t2 when we submit the task t3. The storage of the
> last_task submited to the pool for a given instance is needed when the code
> is not linear but cyclic and the problem appears when these tasks have
> different types. Suppose that the function called return different types,
> std::string and std::size.
>
> class A {
> std::string f( ) {
> return "***********";
> }
>
> std::size g( ) {
> return 5;
> }
> };
>
> A a, b;
>
> void h( ) {
> // do a expensive task
> }
>
>
> Image also that a function f will be called cyclically with values that
> depends on the user input
>
> while () {
> // get an int from cin in variable v
> f(v);
> }
>
> This function will depending onthe parameter submit different actions, but
> no action can be done in parallel for the same instance
> void f(int i) {
> switch (i) {
> case 1:
> tp::task<std::string> t1(
> pool.chained_submit(boost::bind(& A::f,a),
> last_task));
> last_task = t1;
> // forward t1to other program logic needing the result of a.f()
> break;
> case 2:
> tp::task<std::size> t2(
> pool.chained_submit(boost::bind(& A::g,a),
> last_task));
> last_task = t2;
> // forward t2 to other program logic needing the result of
> a.g()
> break;
> case 3:
> pool.submit(h);
> break;
> // other cases ...
> }
> }
>
> How last_task can be declared and initialized? As a task can be
> constructed only by submiting a function to a pool we can submit a function
> that do nothing.
>
> void do_nothing( ) {
> }
>
> tp::task<???> last_task(pool.submit(do_nothing));
>
> What would be the type of last_task that provides the following functions:
> tp::task<???>(tp::task<void>);
> template<typename Act, typename T>
> tp::task< typename result_of< Act() >::type > chained_submit(
> Act const& act,tp::task<???> & t);
> tp::task<???>& operator=(tp::task<std::size>);
> tp::task<???>& operator=(tp::task<std::string>);
>
> The first function is matched by void. As chained_submit do not use at all
> the value stored on the future of the task, a void task coul be enough
> also, but we need a means to copy tp::task<T> on a tp::task<void>.
>
> I think that the future library allows already something like that, i.e. a
> future<void> can be used to wait for a future<T>. Do you think that this
> void specialization for task<void> can be added to your library? Another
> idea, why not define the chained_submit with a future instead of a task as
> parameter?
>
> >> I had already recovered your compressed file as other post let know.
> >> Please
> >> could you point me where the chaining task is described?
> >
> > example_chained_submit and in the docu chapter 'Submiting Tasks'
>
> Sorry, I was seen an older documentation of the threadpool library. I see
> it now.
>
> Vicente
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk