I need to wrote a data structure that is safe to write and read in a program with one writer and one reader threads. The reader can miss data but the data it reads out needs to be as updated as possible and not corrupted. No mutex or other lock mechanisms are to be used. Here is what I come up with:
struct SS
{
SS(int v = 0) : seed(v), square(v * 2) {}
bool ok() const
{
return square == seed * 2;
}
int seed;
int square;
};
SafeData<SS> data;
void *read(void *arg)
{
for (int i = 0; i < 100000000; ++i)
{
SS r = data.read();
if (!r.ok())
{
cout << "corrupted data: " << r.seed << " " << r.square << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
int main(int argc, const char* argv[])
{
pthread_t r_thread;
int ret = pthread_create(&r_thread, NULL, &read, NULL);
if (ret != 0)
{
cerr << "failed to create read thread\n";
exit(-1);
}
for (int i = 0; i < 100000000; ++i)
{
SS w(i);
data.write(w);
}
return 0;
}
My assumption here is that assignment of int is atomic. When I compile it with g++ without optimization, it seemed to work fine. No corrupted data encountered. However, as soon as I use optimization, i.e., g++ -O, I started to see corrupted data randomly.
I don't understand what exactly is going on here. Can someone shed some light here?