Search code examples
c++boostboost-thread

Printing with boost threading library


So I am beginning to write a program to parse and then process a large amount of text. I have set up a class that contains methods which are run as boost threads. As of now each of these threads simply prints some text statement and then return. The code compiles and runs without any errors. However, the text is printed out inconsistently. This is to be expected as the threads are running in parallel, so I tried using a mutex to coordinate use of the output. However, I am clearly doing something wrong as the output is still inconsistent. To add on to this some output is printed twice which I cannot explain as a failure to code the mutex correctly. Below is my code:

/* 
 * File:   ThreadParser.h
 * Author: Aaron Springut
 *
 * Created on Feburary 2, 2012, 5:13 PM
 */

#ifndef THREADPARSER_H
#define THREADPARSER_H

#include <string.h>
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include "FileWordCounter.h"

class ThreadParser {

    public:

    ThreadParser();
    ThreadParser(std::string fileName);



    private:

    //mutex for cout
    boost::mutex coutMut;  

    std::string dataFile;
    FileWordCounter fCounter;

    //threads
    void parseFile();
    void processSearches();



};

#endif     


/* 
 * File:   ThreadParser.cpp
 * Author: Aaron Springut
 *
 * Created on Feburary 2, 2012, 5:13 PM
 */


 #include "ThreadParser.h"

 using namespace std;


 ThreadParser::ThreadParser(){

    double buyNum = 0;
    buyNum = buyNum * 100;
    cout << "Percentage of people buying: "<< buyNum <<"%"<<endl;

 }

 ThreadParser::ThreadParser(string fileName){

    dataFile = fileName;
    double buyNum = 0;

    //create the mutex and aquire a lock on it for this thread

    boost::mutex::scoped_lock(coutMut);

    boost::thread parseThread(boost::bind(&ThreadParser::parseFile, this));
    boost::thread processSearches(boost::bind(&ThreadParser::processSearches,this));

    buyNum = buyNum * 100;
    cout << "Percentage of people buying: "<< buyNum <<"%"<<endl;


 }


 void ThreadParser::parseFile(){

    boost::mutex::scoped_lock(coutMut);
    cout << "parseFileThreadLaunch"<<endl;
    return;

 }


 void ThreadParser::processSearches(){

    boost::mutex::scoped_lock(coutMut);
    cout << "processSearchesLaunch"<<endl;
    return;

 }

As an example of what is going wrong here are two outputs from the program that runs this:

Percentage of people buying: parseFileThreadLaunch
processSearchesLaunch
0%

Okay, cout is not thread safe and I've done something wrong with the mutex.

Percentage of people buying: parseFileThreadLaunch
0%
processSearchesLaunch
processSearchesLaunch

This is confusing, how is the last line being printed twice? Is it a consequence of cout not being thread safe? Or, am I missing part of the bigger picture.

EDIT: The class is being called like so in the main function:

string fileName("AOLData.txt");
cout << fileName<< endl;

ThreadParser tp(fileName);

Solution

  • boost::mutex::scoped_lock(coutMut);
    

    This does not do what you think it does. This creates a temporary, which is immediately destroyed, releasing the lock. Just like int(3);.

    You want:

    boost::mutex::scoped_lock sl(moutMut);
    

    This creates an object, sl, that holds the lock until it goes out of scope.