I'm quite new to boost::threads, I read the documentation and but i'm having some trouble applying it in practice, perhaps you can help? First of all, I have taken the time to write a self contained code listing that demonstrates 2 types of behavior that I cannot yet understand...
The program allows the user to issue 3 different commands,
- task [name]
- info
- quit
The purpose is that task will launch some work on a new thread, but then return back to the command prompt while the work is carried out. The user can give the info command to find out which tasks have completed and which have not.
Im using a dual core Win7 machine and Visual Studio 2008 Express.
Problem 1>
Issuing the command, task p1 p2 p3, starts 3 tasks running. This can be checked by issuing info. After a few seconds the work is complete, however for some reason the completed flag is not always set true on 1 or 2 of the tasks.
Problem 2>
Quiting the program then produces the following message:
Windows has triggered a breakpoint in example.exe. This may be due to a corruption of the heap, which indicates a bug in example.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while example.exe has focus. The output window may have more diagnostic information.
Hopefully you can reproduce this behavior and help.
Thanks in advance. Alex.
//WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED
#include <iostream>
#include <string>
#include <sstream>
#include <boost/thread.hpp>
using namespace std;
class task {
public:
string mname;
bool completed;
void start()
{
int a = 0;
for (int i=0 ; i<10000; i++)
{
for (int j=0 ; j<100000; j++)
{
a= i*2;
}
}
this->completed = true;
}
task(string name)
{
mname = name;
completed = false;
}
};
class taskManager{
public:
boost::thread_group threads;
void startTask( string name )
{
//add new task to vector list
mtasks.push_back( task(name) );
// execute start() on a new thread
threads.create_thread( boost::bind( &task::start, &mtasks.back()) );
}
int tasksTotal()
{
return mtasks.size();
}
string taskInfo(int i)
{
string compstr("Not Completed");
if ( mtasks[i].completed == true )
{
compstr = "Completed";
}
return mtasks[i].mname + " " + compstr;
}
private:
vector<task> mtasks;
};
int main(int argc, char* argv[])
{
string cmd, temp;
stringstream os;
bool quit = false;
taskManager mm;
cout << "PROMPT>";
while (quit == false)
{
//Wait for a valid command from user
getline(cin,cmd);
// Reset stringstream and assign new cmd string
os.clear();
os << "";
os << cmd;
//parse input string
while (os >> temp)
{
if ( temp.compare("task") == 0 )
{
while (os >> temp) { mm.startTask( temp ); }
}
if ( temp.compare("info") == 0 )
{
// Returns a list of all completed and not completed tasks
for (int i = 0; i<mm.tasksTotal(); i++)
{
cout << mm.taskInfo(i).c_str() << endl;
}
}
if ( temp.compare("quit") == 0 ){ quit = true; }
}
cout << "PROMPT>";
}
mm.threads.join_all();
return 0;
};
std::deque
would work here rather thanstd::vector
since the deque won't reallocate existing entries. – Ketron