Tuesday, April 30, 2013

Boost Threads (Part 1)


/**
 * Boost Threads (Part 1)
 *
 * In this example I want to cover basics about Boost Thread. I am completely 
 * new to this topic so I'll be learning as I write. This is being compiled 
 * on Ubuntu 12.10 with Boost 1.49. 
 */

// The following must be included to get boost threads.
#include <boost/thread.hpp>

#include <iostream>
#include <string>

/**
 * A scoped printer object. When constructed it prints that the scope 
 * starts, when finished it prints that the scope ends. Look up info
 * on RAII if you are unsure of what this is doing.
 */
struct printer
{
    //! The label output.
    std::string label;

    printer(std::string const& labelIn)
    : label(labelIn)
    {
        std::cout << "START(" << this->label << ")" << std::endl;
    }

    ~printer()
    {
        std::cout << "END(" << this->label << ")" << std::endl;
    }
};

/**
 * Worker #1 has no arguments. This illustrates basic execution of a thread. [1]
 */
void worker1()
{
    printer P("worker1");

    // You have to create a time object that will denote the duration of 
    // how long this thread will sleep.
    boost::posix_time::seconds workTime(3);

    // Then using the boost::this_thread object, perform the sleep 
    // operation.
    boost::this_thread::sleep(workTime);
}

/**
 * Worker #2 is a little cooler because it demonstrates how to pass arguments
 * into the worker functions. [2]
 */
void worker2(std::string const& extraLabel, int pauseTime)
{
    printer P("worker2 - " + extraLabel);
    boost::posix_time::seconds work2Time(pauseTime);
    boost::this_thread::sleep(work2Time);

}

int main(int, char**)
{
    printer P("main");

    // Create a Worker #1 Thread.
    boost::thread worker1Thread(worker1);

    // Create a couple Worker #2 Threads.
    boost::thread worker2Thread1(worker2, "Pause 4", 4);    
    boost::thread worker2Thread2(worker2, "Pause 2", 2);    

    std::cout << "WAITING(worker2Thread1 - Pause4)" << std::endl;
    worker2Thread1.join();

    std::cout << "WAITING(worker1)" << std::endl;
    worker1Thread.join();

    // This thread should have only paused for 2 seconds, wonder what 
    // happens?
    std::cout << "WAITING(worker2Thread1 - Pause 2)" << std::endl;
    worker2Thread2.join();

    return 0;
}

/**

Results:

START(main)
WAITING(worker2Thread1 - Pause4)
START(worker2 - Pause 2)
START(worker2 - Pause 4)
START(worker1)
END(worker2 - Pause 2)
END(worker1)
END(worker2 - Pause 4)
WAITING(worker1)
WAITING(worker2Thread1 - Pause 2)
END(main)

As you can see, the join doesn't seem to care if the worker's end in a
random way. This is a neat API- unlike serialization where I had to keep 
tweaking and tweaking to make it work right, the threading seemed to 
work out-of-the-box. However this is only a really basic example. Next 
time I will try to do something more interesting.

*/

/**
 * REFERENCES
 *
 * [1] - http://www.codeproject.com/Articles/279053/How-to-get-started-using-Boost-threads
 *
 * [2] - http://www.drdobbs.com/cpp/whats-new-in-boost-threads/211600441
 *
 */

No comments:

Post a Comment