11

In Java, I would do something like:

Thread t = new MyThread();
t.start();

I start thread by calling start() method. So later I can do something like:

for (int i = 0; i < limit; ++i)
{
    Thread t = new MyThread();
    t.start();
}

To create a group of threads and execute the code in run() method.

However, in C++, there's no such thing as start() method. Using Boost, if I want a thread to start running, I have to call the join() method in order to make a thread running.

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

class Worker
{
public:
    Worker() 
    {
        // the thread is not-a-thread until we call start()
    }

    void start(int N)
    {
        m_Thread = boost::thread(&Worker::processQueue, this, N);
    }

    void join()
    {
        m_Thread.join();
    }

    void processQueue(unsigned N)
    {
        float ms = N * 1e3;
        boost::posix_time::milliseconds workTime(ms);

        std::cout << "Worker: started, will work for "
                  << ms << "ms"
                  << std::endl;

        // We're busy, honest!
        boost::this_thread::sleep(workTime);
        std::cout << "Worker: completed" << std::endl;
    }

private:

    boost::thread m_Thread;
};

int main(int argc, char* argv[])
{
    std::cout << "main: startup" << std::endl;

    Worker worker, w2, w3, w5;

    worker.start(3);
    w2.start(3);
    w3.start(3);
    w5.start(3);

    worker.join();
    w2.join();
    w3.join();
    w5.join();
    for (int i = 0; i < 100; ++i)
    {
        Worker w;
        w.start(3);
        w.join();
    }
    //std::cout << "main: waiting for thread" << std::endl;    

    std::cout << "main: done" << std::endl;

    return 0;
}

On the code above, the for loop to create 100 threads, normally I must use a boost::thread_group to add the thread function, and finally run all with join_all(). However, I don't know how to do it with thread function putting in a class which uses various class members.

On the other hand, the loop above will not behave like the loop in Java. It will make each thread execute sequentially, not all at once like the other separated threads, whose own join() is called.

What is join() in Boost exactly? Also please help me to create a group of threads which share the same class.

Amumu
  • 17,924
  • 31
  • 84
  • 131

2 Answers2

15

join doesn't start the thread, it blocks you until the thread you're joining finishes. You use it when you need to wait for the thread you started to finish its run (for example - if it computes something and you need the result).

What starts the thread is boost::thread, which creates the thread and calls the thread function you passed to it (in your case - Worker::processQueue).

The reason you had a problem with the loop is not because the threads didn't start, but because your main thread didn't wait for them to execute before finishing. I'm guessing you didn't see this problem in Java because of the scheduling differences, aka "undefined behavior". after edit In Java the threading behaves slightly differently, see the comment below for details. That explains why you didn't see it in Java.

Here's a question about the boost::thread_group. Read the code in the question and the answers, it will help you.

Community
  • 1
  • 1
littleadv
  • 20,100
  • 2
  • 36
  • 50
  • 2
    In Java, threads are split into two types: normal (non-daemon) and daemon threads, with non-daemon being default. A Java process does not exit until all non-daemon threads have terminated, so what the OP observed is very likely _not_ to be "undefined behaviour". – C. K. Young Jun 05 '11 at 08:40
  • 1
    Ok, thanks, good to know. I'm not a Java programmer, so I'm not aware of the details. – littleadv Jun 05 '11 at 08:42
6

Joining a thread does the same thing in Boost as it does in Java: it waits for the thread to finish running.

Plus, if I remember correctly, Boost's threads run upon construction. You don't start them explicitly.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435