|
Boost Users : |
From: Kirit Sælensminde (kirit.saelensminde_at_[hidden])
Date: 2007-10-30 00:52:24
Andrey Tcherepanov wrote:
> Hello folks,
>
> we recently got stuck with one minor inconvenience with boost thread
> (which we fixed), but somehow we cannot explain why it did not work. We
> are using 1.34.1 and VS 2005 SP1
>
> the sample that did not work properly was aproximately like this (not
> compilable)
>
>
> class Super_Func
> {
> protected:
> bool * _die;
> SomeObscureIPWorksBasedDaemon _daemon;
>
> public:
> Super_Func(bool* t) : _die(t), _daemon("localhost", 12345) {}
>
> void operator()()
> {
> while (!*_die)
> {
> _daemon.do_background_stuff();
> if (_daemon.has_data())
> us_process_data(_daemon.get_data());
> }
> }
> };
>
> int main()
> {
> bool die = false;
> Super_Func sf(&die);
>
> boost::thread main_thread(boost::ref(sf));
> main_thread.join();
>
> return 0;
> }
>
> Everything compiled without hick-up, and even created the thread (well, at
> least debugger showed it, and stopped in while loop). But all the TCP/IP
> related stuff in thread did not work (was sort of stuck).
>
> Once we replaced above with
>
> void Super_Func(bool* die)
> {
> SomeObscureIPWorksBasedDaemon _daemon("localhost", 12345);
> while (!*_die)
> {
> _daemon.do_background_stuff();
> if (_daemon.has_data())
> us_process_data(_daemon.get_data());
> }
> }
>
> int main()
> {
> bool die = false;
> boost::thread main_thread(boost::bind(Super_Func, &die));
>
> main_thread.join();
> return 0;
> }
>
> everything magically worked!
>
> Well, if I do not miss some obvious error somewhere in the first example
> (which I might)... then I do not know why it did not work. I was under
> impression that ref() is just a way to pass "reference" to the anything
> (including functional object), so it will create copy of ref, and not
> Super_Func class itself.
It's probably that the TCP/IP functions initialised in the constructor
for SomeObscureIPWorksBasedDaemon has thread affinity meaning it must be
created in the same thread it will be used from. Your first example
creates the object in the main thread and then tries to use it from
another. In the second example the daemon is created in the same thread
it is used from.
There may also be a difference in visibility of changes to the die
variable between the two, but as it doesn't seem to be set anywhere
you'd not be able to tell (and the effect may be just a delay in the
visibility of a change rather than a failure for the visibility to be
seen across threads).
K
-- http://www.kirit.com/
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net