PDA

View Full Version : Question about implicit sharing



Cruz
17th February 2009, 14:56
I want to make sure I understand this right.

I have an implicitly shared container, say a QHash. Object A creates it and passes it to object B by value.



A
{
QHash;
B.takeThis(QHash);
}


So far, when reading from the QHash both A and B would read from the same memory block, right?

Now A modifies the QHash.



A
{
QHash;
B.takeThis(QHash);
QHash.addElement();
}


Does the QHash get detached in this case? Or only when B modifies its own copy?

And if it does get detached, what happens when A modifies the QHash multiple times? Does it get detached every time?

jpn
17th February 2009, 15:05
So far, when reading from the QHash both A and B would read from the same memory block, right?

Yes, exactly. There are multiple instances of QHash, but the internal data is shared between the instances.



Now A modifies the QHash.

Does the QHash get detached in this case? Or only when B modifies its own copy?

Yes, it gets automatically detached when modifying and if the reference count is greater than one.



And if it does get detached, what happens when A modifies the QHash multiple times? Does it get detached every time?
No, because after detaching in the first place the reference count is updated appropriately. From then on, it's the only occurrence using the modified data. There is no need to detach if the reference count is one.

Cruz
17th February 2009, 15:20
I'm trying to understand the thread safety issue in the following construction:



Thread1()
{
QHash data;

forever
{
data.modify();
Thread2.takeThis(data);

msleep(20);
}
}

Thread2()
{
QHash data;

takeThis(data)
{
this->data = data;
}

forever
{
qDebug() << data;

msleep(20);
}
}


If Thread1 happens to modify the data while Thread2 is qDebug()-ing it, then nothing bad happens, because the data is detached, right?

If above statement is true, then the problem must occur, when takeThis() of Thread2 overwrites it's own data while it's in the process of qDebug()-ing.

And if both statements are true, then I don't understand why the following construction still crashes:



Thread1()
{
QHash data;

forever
{
data.modify();
Thread2.takeThis(data);

msleep(20);
}
}

Thread2()
{
QHash data;
bool reading = false;

takeThis(data)
{
if (!reading)
this->data = data;
}

forever
{
reading = true;
qDebug() << data;
reading = false;

msleep(20);
}
}


I'm trying to find a solution, where Thread1 is not blocked by a mutex when trying to deliver its data, but rather doesn't deliver and continues to calculate the next data set.

jpn
17th February 2009, 15:51
See: atomic operations.

wysota
17th February 2009, 17:03
Just note the difference between reentrancy and thread-safety.