I have the following code:
The header:
class Counter
{
public:
Conuter(const std::string& fileName);
boost::uint16_t getCounter();
private:
tbb::atomic<boost::uint32_t> counter;
std::string counterFileName;
};
The cpp:
Counter::Counter(const std::string& fileName) : counter(), counterFileName(fileName)
{
std::string line;
std::ifstream counterFile (fileName.c_str());
if (counterFile.is_open())
{
getline (counterFile, line);
counterFile.close();
}
boost::uint32_t temp = std::stoul (line,nullptr,0);
counter = temp;
}
boost::uint32_t Counter::getCounter()
{
if (counter > 1000)
{
counter = 0;
}
assert( counter < 1000);
const boost::uint32_t ret = counter++;
if ((counter % 10) == 0)
{
// write the counter back to the file.
std::ofstream file (counterFileName.c_str());
if (file.is_open())
{
myfile << counter;
myfile.close();
}
}
return ret;
}
And elsewhere lets say we have two threads:
boost::thread t1(&Counter::getCounter, counter);
boost::thread t2(&Counter::getCounter, counter);
My question is around the atomic variable. Since the getCounter function can access the counter value up to 3 times per call can the atomic variable change from one call to the next. For example, if the call to if (counter > 1000) fails to pass is there any sort of guarantee that the assert will also pass? Maybe more concretely does the atomic variable block until the end of the function call? Or just as long as the value is being read/written? My second question is, how does the operating system handle the atomic? As in if the atomic doesn't cause the function to block until it is finished, what happens if one thread is updating the variable and one thread is attempting to write it out? Sorry for the abundance of questions this is my first attempt at a lock free data structure.