Jerry's Tutorials: Turning Functions into Threads, 2 of 3

Jerry's Tutorials: Turning Functions into Threads, 2 of 3


The first error that we will fix in the example code is that function main is likely to finish before functions funct1 and funct2.  When function main finishes, the thread objects xxxx and yyyy will go out of scope and their respective destructors will execute.  The practical effect is that functions funct1 and funct2 will be canceled before they are complete.


// This code contains errors. Do not run it until
// we have eliminated all the errors.

#include "stdafx.h"
#include <iostream>
#include <boost/thread.hpp>

void funct1();
void funct2();

int main()
{	
    boost::thread xxxx(funct1);
    boost::thread yyyy(funct2);
    xxxx.join();  // wait for funct1 to finish
    yyyy.join();  // wait for funct2 to finish
    return 0;
}

void funct1()
{
    for (int i = 0; i < 50; i++) std::cout << '?';
    std::cout << std::endl;
}

void funct2()
{
    for (int i = 0; i < 50; i++) std::cout << '!';
    std::cout << std::endl;
}
  • funct1 is supposed to print 50 copies of the character "?" and funct2 is supposed 50 copies of the character "!".  But when I run the program, I get maybe a half dozen or so copies of the character "?" and no copies of the character "!".  funct1 is canceled before it prints all its characters, and funct2 is canceled before it prints any of its characters.
  • The solution is to wait for funct1 and funct2 to finish before the main function terminates.  The boost mechanism to wait for another thread to finish is the join function.  The verb "join" seems like a curious choice to me.  It seems to me that the correct name of the function should be wait or some synonym of wait.  But join it is, so it is join that we use.  The join function is trivial to use.  Simply specify the name of the thread object, followed by the invocation of the join function.
  • It might seem from this example as if it would be handy to have a version of the join function that would wait on both threads instead of having to wait first on one thread and then on the other.  The join function does not have this capability.  But there is a different way that the threads can be created so that a single join can wait on both threads.  This capability will be discussed later in the tutorial.
  • It might seem from this example as if the order of the join functions might matter.  For example, what happens if funct2 completes before funct1? Well, it really doesn't matter.  The main program should not terminate until both threads are completed.  If you join a thread that is already completed, the join function simply becomes a no-operation and returns immediately.  The first join might or might not really have to wait.  The second join might or might not really have to wait.  But after both join's have completed, we can be assured that both threads have completed.

Return to Jerry's Home Page

This page last edited on 23 Mar 2016.