Thread_group semantics
When a thread_group is assigned a task using post, does that task get executed sequentially? Is there a list, so that, when too many posts are added to it, it keeps track of them?
On 9/01/2014 23:40, Quoth Kenneth Adam Miller:
When a thread_group is assigned a task using post, does that task get executed sequentially? Is there a list, so that, when too many posts are added to it, it keeps track of them?
Can you rephrase the question? boost::thread_group does not have a post method.
So, suppose that I give so many tasks to a thread_group that it becomes
more than what the thread pool can handle. I would want the thread pool to
just take longer, but still complete them all. Also, I want the tasks
processed First Come First Serve. What happens when too many tasks are
given to it? Do they get queued up?
On Mon, Jan 13, 2014 at 1:01 AM, Gavin Lambert
On 9/01/2014 23:40, Quoth Kenneth Adam Miller:
When a thread_group is assigned a task using post, does that task get
executed sequentially? Is there a list, so that, when too many posts are added to it, it keeps track of them?
Can you rephrase the question? boost::thread_group does not have a post method.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 14/01/2014 11:21, Quoth Kenneth Adam Miller:
So, suppose that I give so many tasks to a thread_group that it becomes more than what the thread pool can handle. I would want the thread pool to just take longer, but still complete them all. Also, I want the tasks processed First Come First Serve. What happens when too many tasks are given to it? Do they get queued up?
How are you proposing to "give tasks" to a thread_group? Boost.Thread does not provide any mechanism for this. If you want something that does provide a means to queue tasks, have a look at Boost.Asio. The docs for that should answer your questions.
Le 13/01/14 23:21, Kenneth Adam Miller a écrit :
So, suppose that I give so many tasks to a thread_group that it becomes more than what the thread pool can handle. I would want the thread pool to just take longer, but still complete them all. Also, I want the tasks processed First Come First Serve. What happens when too many tasks are given to it? Do they get queued up?
thread_group stores threads not tasks. In addition it is deprecated. I'm working on a basic thread pool in the develop branch. Boost.1.55 contains a first implementation but not yet documented in https://github.com/boostorg/thread/blob/master/include/boost/thread/thread_p..., but the interface will surely change when released https://github.com/boostorg/thread/blob/develop/include/boost/thread/executo.... HTH, Vicente
On Mon, Jan 13, 2014 at 1:01 AM, Gavin Lambert
mailto:gavinl@compacsort.com> wrote: On 9/01/2014 23:40, Quoth Kenneth Adam Miller:
When a thread_group is assigned a task using post, does that task get executed sequentially? Is there a list, so that, when too many posts are added to it, it keeps track of them?
Can you rephrase the question? boost::thread_group does not have a post method.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org mailto:Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Yeah it stores threads, not tasks, but isn't it true that you dispatch jobs to the current thread group using ioService.post? Maybe my question was wrong, because I went off using this recipe http://stackoverflow.com/questions/19500404/how-to-create-a-thread-pool-usin... I should have asked how ioService manages things. On Mon, Jan 13, 2014 at 4:39 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Le 13/01/14 23:21, Kenneth Adam Miller a écrit :
So, suppose that I give so many tasks to a thread_group that it becomes more than what the thread pool can handle. I would want the thread pool to just take longer, but still complete them all. Also, I want the tasks processed First Come First Serve. What happens when too many tasks are given to it? Do they get queued up?
thread_group stores threads not tasks. In addition it is deprecated. I'm working on a basic thread pool in the develop branch. Boost.1.55 contains a first implementation but not yet documented in https://github.com/boostorg/thread/blob/master/include/boost/thread/thread_p..., but the interface will surely change when released https://github.com/boostorg/thread/blob/develop/include/boost/thread/executo... .
HTH, Vicente
On Mon, Jan 13, 2014 at 1:01 AM, Gavin Lambert
wrote: On 9/01/2014 23:40, Quoth Kenneth Adam Miller:
When a thread_group is assigned a task using post, does that task get
executed sequentially? Is there a list, so that, when too many posts are added to it, it keeps track of them?
Can you rephrase the question? boost::thread_group does not have a post method.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing listBoost-users@lists.boost.orghttp://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 14/01/2014 11:49, Quoth Kenneth Adam Miller:
Yeah it stores threads, not tasks, but isn't it true that you dispatch jobs to the current thread group using ioService.post? Maybe my question was wrong, because I went off using this recipe http://stackoverflow.com/questions/19500404/how-to-create-a-thread-pool-usin...
That's a bad recipe. Don't write code like that. (work and the threads are constructed in the wrong order, and stopping immediately after posting will not necessarily execute anything.) Read the Boost.Asio docs (http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio.html) and examples instead. But, to answer your immediate question: Boost.Asio's io_service acts like a queue. It can store an unlimited (except by memory) number of tasks and they are executed in a loosely FIFO order ("loosely" as tasks may execute concurrently and thus apparently out of order when multiple worker threads are used).
Ah ok. Thanks.
On Mon, Jan 13, 2014 at 5:22 PM, Gavin Lambert
On 14/01/2014 11:49, Quoth Kenneth Adam Miller:
Yeah it stores threads, not tasks, but isn't it true that you dispatch
jobs to the current thread group using ioService.post? Maybe my question was wrong, because I went off using this recipe http://stackoverflow.com/questions/19500404/how-to- create-a-thread-pool-using-boost-in-c
That's a bad recipe. Don't write code like that. (work and the threads are constructed in the wrong order, and stopping immediately after posting will not necessarily execute anything.)
Read the Boost.Asio docs (http://www.boost.org/doc/ libs/1_55_0/doc/html/boost_asio.html) and examples instead.
But, to answer your immediate question: Boost.Asio's io_service acts like a queue. It can store an unlimited (except by memory) number of tasks and they are executed in a loosely FIFO order ("loosely" as tasks may execute concurrently and thus apparently out of order when multiple worker threads are used).
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Would it work better if it was threads.join_all() then ioServices.stop()? On Mon, Jan 13, 2014 at 5:29 PM, Kenneth Adam Miller < kennethadammiller@gmail.com> wrote:
Ah ok. Thanks.
On Mon, Jan 13, 2014 at 5:22 PM, Gavin Lambert
wrote: On 14/01/2014 11:49, Quoth Kenneth Adam Miller:
Yeah it stores threads, not tasks, but isn't it true that you dispatch
jobs to the current thread group using ioService.post? Maybe my question was wrong, because I went off using this recipe http://stackoverflow.com/questions/19500404/how-to- create-a-thread-pool-using-boost-in-c
That's a bad recipe. Don't write code like that. (work and the threads are constructed in the wrong order, and stopping immediately after posting will not necessarily execute anything.)
Read the Boost.Asio docs (http://www.boost.org/doc/ libs/1_55_0/doc/html/boost_asio.html) and examples instead.
But, to answer your immediate question: Boost.Asio's io_service acts like a queue. It can store an unlimited (except by memory) number of tasks and they are executed in a loosely FIFO order ("loosely" as tasks may execute concurrently and thus apparently out of order when multiple worker threads are used).
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 14/01/2014 13:26, Quoth Kenneth Adam Miller:
Would it work better if it was threads.join_all() then ioServices.stop()?
No, that would make it block forever. You must do one of the following: 1. create an io_service. 2. create an io_service::work. 3. create threads for your thread_group. 4. at any time after this, post work to the service. 5a. only on shutdown, call stop() and join_all(), in that order. Note that this may result in some posted work not getting called, and therefore some resources not cleaned up. 5b. OR instead of calling stop(), destroy the io_service::work you created earlier (and if you're using ASIO async operations, you must also cancel or close anything outstanding that you don't want to wait for), and then call join_all(). this will block until all posted work is completed. OR 1. create an io_service. 2. post work to the service. (can only be done here, or from inside a callback called by the service) 3. create threads for your thread_group. 4. call join_all(), which will block until all pending work is done. The former lets you make a threadpool you can keep around for the life of your app, and post work as desired. The latter lets you make a threadpool to execute a single blocking task with multiple concurrent subtasks. (Other variations are possible of course but the order of the above is important.)
Yeah, but I want to be able to create a thread_pool in the creating thread
and then move on, posting work to it whenever. In your shutdown
descriptions for the first way to do it, you seem to describe no way to
make sure that all work posted to it gets completed.
I haven't read all of asio's documentation yet. I will though, it's on my
list.
On Mon, Jan 13, 2014 at 6:51 PM, Gavin Lambert
On 14/01/2014 13:26, Quoth Kenneth Adam Miller:
Would it work better if it was threads.join_all() then ioServices.stop()?
No, that would make it block forever.
You must do one of the following:
1. create an io_service. 2. create an io_service::work. 3. create threads for your thread_group. 4. at any time after this, post work to the service. 5a. only on shutdown, call stop() and join_all(), in that order. Note that this may result in some posted work not getting called, and therefore some resources not cleaned up. 5b. OR instead of calling stop(), destroy the io_service::work you created earlier (and if you're using ASIO async operations, you must also cancel or close anything outstanding that you don't want to wait for), and then call join_all(). this will block until all posted work is completed.
OR
1. create an io_service. 2. post work to the service. (can only be done here, or from inside a callback called by the service) 3. create threads for your thread_group. 4. call join_all(), which will block until all pending work is done.
The former lets you make a threadpool you can keep around for the life of your app, and post work as desired. The latter lets you make a threadpool to execute a single blocking task with multiple concurrent subtasks.
(Other variations are possible of course but the order of the above is important.)
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 14/01/2014 14:05, Quoth Kenneth Adam Miller:
Yeah, but I want to be able to create a thread_pool in the creating thread and then move on, posting work to it whenever. In your shutdown descriptions for the first way to do it, you seem to describe no way to make sure that all work posted to it gets completed.
Read 5b in the first method again. Basically the thread pool stays alive (and cannot be joined without blocking) as long as there is any outstanding work, and nobody has called stop() yet (and calling stop will potentially abandon queued but not yet started work). If there will be a time that you do not have any "real" work queued to the io_service, then you must create an io_service::work object to act as "fake" work that keeps the threads alive. But consequently, if you try to join the thread_group while that work object still exists, the joins will block indefinitely. So you need to keep the work object alive for as long as you want to be able to queue additional work to the service, and destroy it prior to joining while shutting down the service. Note that you still might need to do other things to achieve a clean shutdown, such as cancelling pending operations or setting flags to prevent a completed operation from queuing additional operations. (For example, with I/O it's common to have the read/write completed callback post the next read/write request, and you probably don't want to do that sort of thing while you're trying to shut down.)
participants (3)
-
Gavin Lambert
-
Kenneth Adam Miller
-
Vicente J. Botet Escriba