[thread] "almost works" clarification
Hello, Okay, so without starting a flame war, because that is not my intention... Also bear in mind, I am coming from an informed C# .NET frame of mind having worked with .NET threading, synchronization, events, and so forth. I ran across this article, which although a bit dated, is a pretty good sketch of what I would consider a fairly robust thread runner abstraction, which if you read past the frustration, makes good sense, at least in my opinion: http://peter.bourgon.org/blog/2008/12/12/boost-thread-kindof-sucks.html. Nothing against the author, I might turn that around and couch it instead: boost-thread-almost-works: in the sense that, while there are indeed a rich set of primitives provided to hide the details of pthread, Win32 threading, or what have you, it stops just short of providing that abstraction layer for what Peter and I (probably just he and I) consider a robust runner, monitor, and worker. The ingredients are there, though, and with a little bit of persuading, can compose a fairly robust little set of threaded runners. Okay, with that said, am I correct in understanding, the combination of condition and mutex facilitates the analog to C# .NET AutoResetEvent or ManualResetEvent (loosely, ResetEvent) type thing? In other words, thread keeps-on-a-runnin' until condition is notified, at which point thread loop(s) know to stop working when they check in with their conditioned mutex? In other words, mechanically speaking, a worker-bee that starts obtains a lock on the mutex. While the worker is running, on-lookers may poll the monitor for thread completion (which times out as long as the worker-bee is running and has a scoped lock), or otherwise signal the thread to complete through the notify mechanism (which tells the worker-bee to return, which clears the lock). The worker-bee runs until it is completed or its conditioned mutex has been notified (whichever comes first). In another rendition, I was actually using the thread-interruption mechanism, which I may still do, is another way of signaling a thread that it should stop what it's doing. However, seems a bit less graceful than routing requests through a formalized abstraction layer I think, except through creative use of interrupt disabled (which I was also using), but is something else to consider. Anywho, food for thought. Comments, critiques welcome. Thank you... Regards, Michael Powell
Hello, Hi, Okay, so without starting a flame war, because that is not my intention... Also bear in mind, I am coming from an informed C# .NET frame of mind having worked with .NET threading, synchronization, events, and so forth.
I ran across this article, which although a bit dated, is a pretty good sketch of what I would consider a fairly robust thread runner abstraction, which if you read past the frustration, makes good sense, at least in my opinion: http://peter.bourgon.org/blog/2008/12/12/boost-thread-kindof-sucks.html. This is a really old blog. From my quick reading it show how powerful
Le 21/05/13 23:58, Michael Powell a écrit : the Boost.Thread design is. The user can create its own abstraction very easily.
Nothing against the author, I might turn that around and couch it instead: boost-thread-almost-works: in the sense that, while there are indeed a rich set of primitives provided to hide the details of pthread, Win32 threading, or what have you, it stops just short of providing that abstraction layer for what Peter and I (probably just he and I) consider a robust runner, monitor, and worker. The ingredients are there, though, and with a little bit of persuading, can compose a fairly robust little set of threaded runners.
Okay, with that said, am I correct in understanding, the combination of condition and mutex facilitates the analog to C# .NET AutoResetEvent or ManualResetEvent (loosely, ResetEvent) type thing? In other words, thread keeps-on-a-runnin' until condition is notified, at which point thread loop(s) know to stop working when they check in with their conditioned mutex?
In other words, mechanically speaking, a worker-bee that starts obtains a lock on the mutex. While the worker is running, on-lookers may poll the monitor for thread completion (which times out as long as the worker-bee is running and has a scoped lock), or otherwise signal the thread to complete through the notify mechanism (which tells the worker-bee to return, which clears the lock). The worker-bee runs until it is completed or its conditioned mutex has been notified (whichever comes first).
In another rendition, I was actually using the thread-interruption mechanism, which I may still do, is another way of signaling a thread that it should stop what it's doing. However, seems a bit less graceful than routing requests through a formalized abstraction layer I think, except through creative use of interrupt disabled (which I was also using), but is something else to consider.
I'm not sure to understand what your want. Please don't give solutions, just tell us what you want to achieve. Best, Vicente
On 05/21/2013 11:58 PM, Michael Powell wrote:
I ran across this article, which although a bit dated, is a pretty good sketch of what I would consider a fairly robust thread runner abstraction, which if you read past the frustration, makes good sense, at least in my opinion: http://peter.bourgon.org/blog/2008/12/12/boost-thread-kindof-sucks.html.
The worker in this blog has a synchronization error. If stop() is called before run() -- this could happen due to thread scheduling -- then it will not stop. If you can live without the notify_all() in stop(), then a better solution is to pass a cancellation callback as an argument to run(), and check this instead of checking m_running. Something like this: class cancellation { // Use atomic<bool> virtual bool is_cancelled() const = 0; }; class worker { void run(cancellation& state) { while (!state.is_cancelled()) { } } };
On Wed, May 22, 2013 at 5:21 AM, Bjorn Reese
On 05/21/2013 11:58 PM, Michael Powell wrote:
I ran across this article, which although a bit dated, is a pretty good sketch of what I would consider a fairly robust thread runner abstraction, which if you read past the frustration, makes good sense, at least in my opinion: http://peter.bourgon.org/blog/2008/12/12/boost-thread-kindof-sucks.html.
The worker in this blog has a synchronization error. If stop() is called before run() -- this could happen due to thread scheduling -- then it will not stop.
If you can live without the notify_all() in stop(), then a better solution is to pass a cancellation callback as an argument to run(), and check this instead of checking m_running. Something like this:
Yessir, this is not a half-bad thought actually, encapsulate the canceled, or more generically "state" of which one mode is the cancel request, could be others, like timeout, etc. HTH
class cancellation { // Use atomic<bool> virtual bool is_cancelled() const = 0; };
class worker { void run(cancellation& state) { while (!state.is_cancelled()) {
} } };
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 21/05/2013 23.58, Michael Powell wrote:
Hello,
Okay, so without starting a flame war, because that is not my intention... Also bear in mind, I am coming from an informed C# .NET frame of mind having worked with .NET threading, synchronization, events, and so forth.
I ran across this article, which although a bit dated, is a pretty good sketch of what I would consider a fairly robust thread runner abstraction, which if you read past the frustration, makes good sense, at least in my opinion: http://peter.bourgon.org/blog/2008/12/12/boost-thread-kindof-sucks.html.
Nothing against the author, I might turn that around and couch it instead: boost-thread-almost-works: in the sense that, while there are indeed a rich set of primitives provided to hide the details of pthread, Win32 threading, or what have you, it stops just short of providing that abstraction layer for what Peter and I (probably just he and I) consider a robust runner, monitor, and worker. The ingredients are there, though, and with a little bit of persuading, can compose a fairly robust little set of threaded runners.
Okay, with that said, am I correct in understanding, the combination of condition and mutex facilitates the analog to C# .NET AutoResetEvent or ManualResetEvent (loosely, ResetEvent) type thing? In other words, thread keeps-on-a-runnin' until condition is notified, at which point thread loop(s) know to stop working when they check in with their conditioned mutex?
In other words, mechanically speaking, a worker-bee that starts obtains a lock on the mutex. While the worker is running, on-lookers may poll the monitor for thread completion (which times out as long as the worker-bee is running and has a scoped lock), or otherwise signal the thread to complete through the notify mechanism (which tells the worker-bee to return, which clears the lock). The worker-bee runs until it is completed or its conditioned mutex has been notified (whichever comes first).
In another rendition, I was actually using the thread-interruption mechanism, which I may still do, is another way of signaling a thread that it should stop what it's doing. However, seems a bit less graceful than routing requests through a formalized abstraction layer I think, except through creative use of interrupt disabled (which I was also using), but is something else to consider.
Anywho, food for thought. Comments, critiques welcome. Thank you...
Regards,
Michael Powell
If you are trying to say that boost::thread is too low level for you, we can talk about it. If you say instead that bogus Monitor implementation is something to adopt or even use then you are totally wrong. Let's ignore the fact that the article is a tad dated. Having a Thread polling to check if he has to terminate his main loop it's a totaly waste, that's why basically people needs hardware more more and more powerful, because they just waste it. Instead of a solution (bugged) please explain what you are not able to achieve with the current boost thread. Also the Author is assuming that boost::thread is there to totally simplify the usage of pthread. boost::thread is there to permit you to write platform independent multi threaded code. Regards Gaetano Mendola
On 05/25/2013 02:34 PM, Gaetano Mendola wrote:
Instead of a solution (bugged) please explain what you are not able to achieve with the current boost thread.
I cannot speak on behalf of the original poster, but I have seen this complaint before, so I will take a stab at it. The basic complaint is that boost::thread abstraction is too low-level for certain common use cases. This is not necessarily a complaint about boost::thread itself. Keep in mind that the average application programmer is not intimately familiar with threading, and will prefer any solution that allows him to focus on the application logic rather than on threading mechanisms. In the most common use case that I have encountered, people are looking for two improvements. First, a recognizable entry-point (the MyWorker::run() in the blog example.) Second, a polite way to notify the thread that it should shut down (the MyWorker::stop() in the blog example.) The first improvement is not important, so I will disregard it here. The typical solutions to the second improvement are to use condition variables, interruption-points, or message passing. Condition variables are doable, but you can easily introduce threading errors in your application code (as the blog example demonstrates.) With interruption-points you have to catch the exceptions to handle the shut down. In some cases this can result in complex application code. Furthermore, the application programmer has to make sure that his code executes some interruption point. Message passing is nice, but only if you already are using a thread-safe message queue. Otherwise, it is a bit of an overkill solution to shut down a thread.
participants (4)
-
Bjorn Reese
-
Gaetano Mendola
-
Michael Powell
-
Vicente J. Botet Escriba