$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [gsoc-2013] Boost.Thread/ThreadPool project
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-05-02 11:15:57
Le 02/05/13 11:58, Dan Lincan a écrit :
> Hello,
>
> I have updated my proposal following your guide and tried to answer
> and give solution to most of the problems. I have tried to separate
> the interface with the implementation details so when choosing an
> interface a feature can be easily added by following the exact
> interface header so multiple implementations can be used without
> affecting the user(ex: scheduling algorithm for dynamic thereads,
> bounded/unbounded queues etc). I hope this approach is better.
>
> You can find the pdf version here [1]. The previous version of the
> proposal can be found here [2].
>
> Thank you very much for the feedback, suggestions, guidance and the
> really fast answers.
>
> [1] http://danlincan.3owl.com/gsoc/final-proposal.pdf
> [2] http://danlincan.3owl.com/gsoc/Proposal.pdf
>
Hi Dan,
*The new proposal contains:*
*Waitable tasks*
This feature gives the user the option to wait for a task to finish and 
retrieve its result.
Drawback is that maybe the user is not interested in the result of the task.
Interface
template<classFunction,class...Args >
boost::future<typenameboost::result_of<Functionf()>::type>
submit(Function&&f, Args&&args);
My comments:
what do you think of separating the responsabilities, the thread pool 
schedules Callables (void()) and a submit free function manage with futures:
class thread_pool {
public:
  template<class Callable >
  void submit(Callable&&);
  ...
};
template<typename, Executor, class Function,class... Args >
boost::future<typename boost::result_of<Function (Args...)>::type>
submit(Executor& e, Function&& f, Args&& args);
Implementing this function needs to use the same techniques than 
boost::async()*
The new proposal contains:*
*Task scheduling priority*
The user would be allowed to give the tasks a priority, something 
similar to the operating system process priority: low, medium, high etc.
Performance is lost when the algorithm to schedule tasks is running. 
Based on the implementation, this can be more that O(1), thus big 
overhead. Another problem is fair scheduling. Low priority tasks have to 
run at some point even if only high priority tasks are being submitted 
to the threadpool.
Interface
template<classFunction,class...Args ,class Priority>
boost::future<typenameboost::result_of<Functionf()>::type>
submit(Function&&f, Args&&args, Priorityp = default_priority());
My comments:
I don't think adding priorities in this way would improve the performances.
*The new proposal contains:*
*Task execution order*
For example the user might want x tasks to be executed, then only after 
all x have been executed another y can be executed and so on. So the 
user could assign the priority 1 to the x tasks and 2 to y tasks. The 
threadpool will know that level 2 tasks can only be executed after level 
1 tasks are done.
Performance is lost when a task is chosen to be executed. For example, 
if using priority queues, the complexity would be O(logn) plus the locks 
which can slow down a lot the scheduling.
This feature can be used as a kind of serial executor by giving higher 
and higher numbers to the order argument.
Interface
template<class Function,class...Args ,class Order>
boost::future<typenameboost::result_of<Functionf()>::type>
*submit**(**Function**&&***f*, **Args&&*args*, **Order*o= default_order());
*Callback functions / Continuations*
The user can also set a callback function when submitting a task to the 
threadpool. This function will run as soon as the task is finished by 
the threadpool.
Drawback: Since the callback function is runned by the thread which 
executs the task, this thread can be block if the callback function is 
blocking. Also the callback has no parameters.
Interface
template<class Function,class...Args ,class Callback>
boost::future<typenameboost::result_of<Functionf()>::type>
*submit**(**Function**&&***f*, **Args&&*args*, **Callback*c= 
default_callback());
My comments:
I prefer continuations than callbacks and prefer an interface that 
explicitly states the dependencies.
when_all(submit(f), submit(g)).then(h);
*The new proposal contains:*
*Task cancellation*
With this feature the use can cancel a submitted task. If the task is 
currently being executed it will be interrupted. For implementation 
boost::thread::intterupts will be activated.
template<class Function,class...Args ,class Callback,class Task>
boost::future<typenameboost::result_of<Functionf()>::type>
*submit**(**Function**&&***f*, **Args&&*args*, ****Task&*task);
Task has the function cancel which cancels/interrupts when called.
My comments:
This is a little bit complex from the users point of view.
I guess the best is to either:
* adding to boost::future the possibility to interrupt the task, or
* returning a interrupted_future<T> or task<T> that can be interrupted.
There is an additional requirement. The user must ensure that all the 
tasks related to some object are executed sequentially but the task 
submission don't knows about the pending tasks.
Continuations don't solve the problem. What would you add to make the 
users life easier?  (please read the discussion about threadpool and 
ASIO, the answer is someway there).
Best,
Vicente