July 22, 2005
>>>   QString s;
>>>   thread 1: s[0] = 'a';
>>>   thread 2: QString y(s); y[0]; y[0];
>>> which can result in the y[0] returning different values in thread 2.
>>
>> Yes, of course. As a char[] is not implicitly shared, you cannot expect
>> thread-safety here. You have to work with QStrings throughout to play
>> safe. But, personally, i don't like this programming paradigm. I normally
>> think in terms of "ownership", and dup when the owner changes.
>
> These are QStrings everywhere - no char[]'s. Use "at" or any modifying
> operator if operator[] looks too much like char[].

Ok i see. Well, in this case the above example will return the same values even in a multithreaded environment. That's because s[0] = 'a' takes a copy of the string (there are 2 references on it).

Ciao
uwe
July 22, 2005
"Uwe Salomon" <post@uwesalomon.de> wrote in message news:op.subsrszr6yjbe6@sandmann.maerchenwald.net...
>>>>   QString s;
>>>>   thread 1: s[0] = 'a';
>>>>   thread 2: QString y(s); y[0]; y[0];
>>>> which can result in the y[0] returning different values in thread 2.
>>>
>>> Yes, of course. As a char[] is not implicitly shared, you cannot expect
>>> thread-safety here. You have to work with QStrings throughout to play
>>> safe. But, personally, i don't like this programming paradigm. I
>>> normally
>>> think in terms of "ownership", and dup when the owner changes.
>>
>> These are QStrings everywhere - no char[]'s. Use "at" or any modifying operator if operator[] looks too much like char[].
>
> Ok i see. Well, in this case the above example will return the same values even in a multithreaded environment. That's because s[0] = 'a' takes a copy of the string (there are 2 references on it).
>
> Ciao
> uwe

The "s" is global reference. Here's what I'm arguing happens:

1) s is constructed and filled with some data. It is the sole owner of the
data so the ref count is 1.
2) Thread 1 enters the s[0] = 'a' statement. The operator[] makes and
returns a QCharRef (which contains a field str of type QString& not a
QString so it does not increment the ref count for s).
3) Thread 1 starts to evaluate the assignment. The QCharRef assignment
operator has the following code
  if (str.count > 1) expand(); // dup if multiple refs
  str.data[i] = val;
so since the ref count is 1 it does not duplicate the data. Now between the
if statement and the std.data[i]=val suppose a thread context switch happens
and
4) Thread 2 enters the constructor QString y(s) which increments the ref
count and shares the data pointer with s.
5) Thread 2 evaluates the y[0] statement which reads the shared array item
0. Note that reading a string does not check the ref count.
6) Thread 1 switches back in and evaluates the assignment str.data[i] = val
7) Thread 2 switches and evaluates the y[0] which now picks up the new value
in the shared data.

So I'm arguing it can be pretty subtle just what is allowed with QString and what isn't. The documentation for QString is correct and the case I've described above is not contradicting their documentation since the threading switches involve a shared reference "s".


July 22, 2005
> So I'm arguing it can be pretty subtle just what is allowed with QString and
> what isn't. The documentation for QString is correct and the case I've
> described above is not contradicting their documentation since the threading switches involve a shared reference "s".

You are right, of course. Well, quirky tricks always come with some caveats...

Ciao
uwe
1 2 3 4 5 6
Next ›   Last »