12

Some people seem to launch boost::threads using the boost::bind() function, like in the accepted answer of the following question:

Using boost thread and a non-static class function

Whereas other people don't use it at all, like in the answer with the most upvotes of this question:

Best way to start a thread as a member of a C++ class?

So, what's the difference, if it exists?

deinocheirus
  • 1,833
  • 5
  • 26
  • 44
  • So I think you're really asking why use Boost for threads over (native) p-threads? – ScoPi Dec 06 '12 at 11:31
  • 2
    @ScoPi: No, I think he's asking why to use `bind` rather than just letting the `boost::thread` constructor do all the work. (And I'm pretty sure you need to use `bind` if you want to start the thread using a `shared_ptr`.) – David Schwartz Dec 06 '12 at 11:32

5 Answers5

14

As you can see by the code below that compile and gives the expected output, boost::bind is completely unnecessary for using boost::thread with free functions, member functions and static member functions:

#include <boost/thread/thread.hpp>
#include <iostream>

void FreeFunction()
{
  std::cout << "hello from free function" << std::endl;
}

struct SomeClass
{
  void MemberFunction()
  {
    std::cout << "hello from member function" << std::endl;
  }

  static void StaticFunction()
  {
    std::cout << "hello from static member function" << std::endl;
  }
};

int main()
{
  SomeClass someClass;

  // this free function will be used internally as is
  boost::thread t1(&FreeFunction);
  t1.join();

  // this static member function will be used internally as is
  boost::thread t2(&SomeClass::StaticFunction);
  t2.join();

  // boost::bind will be called on this member function internally
  boost::thread t3(&SomeClass::MemberFunction, someClass);
  t3.join();
}

Output:

hello from free function
hello from static member function
hello from member function

The internal bind in the constructor does all the work for you.

Just added a few extra comments on what happens with each function type. (Hopefully I've read the source correctly!) As far as I can see, using boost::bind externally will not cause it to also double up and be called internally as it will pass through as is.

goji
  • 6,911
  • 3
  • 42
  • 59
  • 1
    So why do people use it? This boost::asio example uses bind() too: http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/chat/chat_client.cpp – deinocheirus Dec 06 '12 at 11:43
  • @user1613 it could depend on the version of boost. The variant without `std::bind` requires some kind of variadic template emulation. – juanchopanza Dec 06 '12 at 11:45
  • It has been supported at least as far back as 2008 occording to Anthony Williams Dr Dobbs article on Boost.Thrads: http://www.drdobbs.com/cpp/whats-new-in-boost-threads/211600441 I would suspect people do it purely out of habit. Without looking at the source, this probably means boost::bind is called twice if you use it externally. – goji Dec 06 '12 at 11:48
  • What about using a `shared_ptr` to call a member function? Does it ensure a copy of the shared pointer stays in scope through the execution of the member function? – David Schwartz Dec 06 '12 at 12:23
  • 3
    People probably use `boost::bind` because they are unaware of `boost::thread`'s internal bind – mark Dec 06 '12 at 12:24
  • @DavidSchwartz of course, boost::bind will create a functor internally storing the shared_ptr for the lifetime of the thread. It's identical to if you did it yourself, only it's done on your behalf. – goji Dec 06 '12 at 12:29
  • @mark I'm asking mainly because it looks unlikely to me that even boost::asio's author is unaware of that... I think I'll update my question. – deinocheirus Dec 06 '12 at 13:43
  • @user1613 I have to admit I was unaware of it until today - but then again I haven't had a lot of exposure to `boost::thread` (recently I have been using `std::thread`. – mark Dec 06 '12 at 14:57
  • @Troy: I agree. It appears there's no need to do the bind under any conditions I can think of. – David Schwartz Dec 06 '12 at 16:35
11

There is no difference - thread contructor uses bind internally. People use bind explicitly for historical reasons, because Boost.Thread didn't have a "binding" constructor before 1.36.

Igor R.
  • 14,716
  • 2
  • 49
  • 83
1

The boost::bind is used to bind a member function to a thread, whereas without boost::bind normally you're using a static function or a free function with the thread.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
1

So, what's the difference, if it exists?

The main difference is what do you need to access within the thread function.

If your design requires that you access a class instance's data, then launch your thread as part of a class instance (use boost::bind with this and a member function, or a static member function with a void* mapped to this - that's a matter of style mostly).

If your design requires that the thread function is not dependent on a particular object's data, then use a free function.

utnapistim
  • 26,809
  • 3
  • 46
  • 82
0

The primary difference is whether you want to interface static or non-static member functions. If you want to use non-static member functions as the function launched by the thread, you must use something like bind.

The proposed alternative (the second question you linked) is to use a static method that takes a pointer to the class object and can then call any of it's members. This clears up the syntax slightly but the biggest advantage (to me) is that you don't need to include something like Boost to get bind. But if you are using boost::threads you might as well take boost::bind also. Note, C++ 11 has std::bind so you could use bind with pthreads as well and not introduce any extra dependency such as Boost, but that's if you want to use C++ 11.

I don't see a compelling syntax reason to avoid using bind over having a static method that calls member functions. But that is more a matter of personal preference.

tpg2114
  • 14,112
  • 6
  • 42
  • 57