I have been practicing multi-threading before using the Windows.H library provided by Windows SDK. Now I'm trying to learn to create more portable applications by using as many Unix based libraries as much as possible that can also run in Windows. One of the best libraries out there is Boost. Now using Cygwin as my simulated Unix environment, I'll be studying multi-threading. I have already built the Boost library under Cygwin using this guide. You can refer to this article on how to install Cygwin with the necessary packages needed to compile the Boost library.
Now I'll be trying to build some simple applications using the gcc, g++ and c++ compiler packaged with Cygwin. This is the first code that I tested:
Example 01: boost_threading.c++
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
bool requeststop = false;
bool finishedjob = false;
void workerFunc()
{
std::cout << "Worker: running" << std::endl;
// Pretend to do something useful...
boost::posix_time::seconds workTime(4);
const boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
for (int i=0; i<20; i++){
if (requeststop == true)
{
std::cout << "worker forced to stop." << std::endl;
break;
}
boost::this_thread::sleep(workTime);
const boost::posix_time::ptime worker_now = boost::posix_time::second_clock::local_time();
std::cout << "work: doing something " << i << " time: " << worker_now << std::endl;
}
finishedjob = true;
}
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc);
std::cout << "main: waiting for worker thread" << std::endl;
boost::posix_time::seconds workTime(3);
for (int i=0; i<9; i++){
if (finishedjob==true)
{
std::cout << "worker is already finished." << std::endl;
break;
}
boost::this_thread::sleep(workTime);
const boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
std::cout << "asking for the " << i << " time, do you wish to quit (y/n): " << now << std::endl;
char ans = 'x';
std::cin >> ans;
if (ans == 'y')
{
std::cout << "requesting worker to stop." << std::endl;
requeststop = true;
break;
}
else if (ans == 'n')
requeststop = false;
}
workerThread.join();
std::cout << "main: done" << std::endl;
return 0;
}
The code was orginally an example from a multi-threading guide for Boost. I made a lot of modifications to simulate a real-time situation. However for debugging purposes there are a lot of printf's in the code. Anyway, it works if compiled with Visual Studio C++ 2008 and the C++ compiler of Cygwin. To compile, I used the following format of the command under Cygwin:
c++ -I /path-to-boost/boost_1_45_0 /path-to-code/boost_threading.c++ -o boost_threading.exe /path-to-lib/libboost_thread.dll.a /path-to-lib/libboost_date_time.dll.a"
I compiled my Boost libraries, and they came out with the following file names libboost_thread.dll.a
and libboost_date_time.dll.a
among others. As shown in the C++ code above I'm using two libraries thread.hpp
and date_time.hpp
, hence we are required to address the related libraries that are used to link these headers. However, the real header files are already linked with -I
(include) option that is already pointed to the boost_1_45_0
folder.
In the first example above, when you run the program, it immediately starts a worker thread that sleeps four seconds and prints status twenty times. The main thread will continue as is and will ask you in the beginning of the program if you wish for the worker thread to stop, if you type y
, it will change the sentinel value of a variable requeststop
to true and that will cause the worker to stop and ultimately workerThread.join() will cause it to join the main()
once again.
It should be obvious that the worker thread is the function workerFunc()
run by the line boost::thread workerThread(workerFunc)
in the very beginning of the main()
function. And workerThread.join()
on the other hand forces the worker thread to join the main()
after it's done or if terminated as requested by requeststop
if it's true.
December 12, 2010 01:02 AM