I'm now trying to find my feet in lock-free programming. In particular I am curious about possible reordering for different memory semantics.
Consider the following example. There are two threads (producer and consumer). Release-acquire memory order is used for synchronization.
#include <QCoreApplication>
#include <QDebug>
#include <QtConcurrent>
QAtomicPointer<QString> ptr;
int data;
void producer()
{
data = 42;
ptr.storeRelease(p);
}
void consumer()
{
//while (!(p2 = ptr.load())) // ?
while (!(p2 = ptr.loadAcquire()))
;
Q_ASSERT(*p2 == "Hello"); // never fires
Q_ASSERT(data == 42); // never fires
}
int main(int argc, char *argv[])
{
QtConcurrent::run(producer);
QtConcurrent::run(consumer);
return a.exec();
}
#include <QCoreApplication>
#include <QDebug>
#include <QtConcurrent>
QAtomicPointer<QString> ptr;
int data;
void producer()
{
QString* p = new QString("Hello");
data = 42;
ptr.storeRelease(p);
}
void consumer()
{
QString* p2;
//while (!(p2 = ptr.load())) // ?
while (!(p2 = ptr.loadAcquire()))
;
Q_ASSERT(*p2 == "Hello"); // never fires
Q_ASSERT(data == 42); // never fires
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QtConcurrent::run(producer);
QtConcurrent::run(consumer);
return a.exec();
}
To copy to clipboard, switch view to plain text mode
I'm wondering why it is necessary to use release-acquire semantics here? What might happen if we used the relaxed load in consumer?
Bookmarks