I made the following sample program to play with boost threading:
#pragma once
#include "boost\thread\mutex.hpp"
#include <iostream>
class ThreadWorker
{
public:
ThreadWorker() {}
virtual ~ThreadWorker() {}
static void FirstCount(int threadId)
{
boost::mutex::scoped_lock(mutex_);
static int i = 0;
for(i = 1; i <= 30; i++)
{
std::cout << i << ": Hi from thread: " << threadId << std::endl;
}
}
private:
boost::mutex mutex_;
};
main class:
// ThreadTest.cpp
#include "stdafx.h"
#include "boost\thread\thread.hpp"
#include "ThreadWorker.h"
int _tmain(int argc, _TCHAR* argv[])
{
boost::thread thread1(&ThreadWorker::FirstCount, 1);
boost::thread thread2(&ThreadWorker::FirstCount, 2);
boost::thread thread3(&ThreadWorker::FirstCount, 3);
thread1.join();
thread2.join();
thread3.join();
std::string input;
std::cout << "Press <enter> to finish...\n";
std::getline( std::cin, input );
return 0;
}
When I run this I get the following output:
1: Hi from thread: 1
1: Hi from thread: 3
2: Hi from thread: 3
...
It looks like thread 1 gets there first and then thread 3. Isn't the scoped_lock supposed to prevent other threads from entering that section of code? Shouldn't the first thread that runs FirstCount() go to completion?
UPDATE
One thing I think is wrong with my code is this line:
boost::mutex::scoped_lock(mutex_);
I think it should be like:
boost::mutex::scoped_lock xyz(mutex_);
Once I do that, it does make the complaint about mutex_ not being static. Why it worked in the first place I'm not sure. Changing mutex_ to static does gives me a linking error:
1>ThreadWorker.obj : error LNK2001: unresolved external symbol "private: static class boost::mutex ThreadWorker::mutex_" (?mutex_@ThreadWorker@@0Vmutex@boost@@A) 1>c:\something\ThreadTest\Debug\ThreadTest.exe : fatal error LNK1120: 1 unresolved externals
Still playing with it.
You have two errors:
First of all, as already noticed, mutex_
should be static also:
private:
static boost::mutex mutex_;
and of course declare it somewhere (in a .cpp file preferably!):
boost::mutex ThreadWorker::mutex_{};
Now, why does the compiler not complain? Well, because you actually do not construct a scoped lock with argument mutex_
here:
boost::mutex::scoped_lock(mutex_);
Actually this will not call the constructor that you want, but create a (local) object mutex_
that is of type scoped_lock
and is constructed by the default constructor. Hence, no compiler issues. You should change it to something like the following:
boost::mutex::scoped_lock l{mutex_};
Now the compiler should start complaining about mutex_
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With