Could you please elaborate more on *why*? I just can't see
that happening.
Let's assume we have two threads running, A and B. Thread A
owns a string which it wants to pass to thread B. How does it
do that?
It copies the string, and passes a copy to B. There's no need
to lock for the copy, unless the copy is part of a larger
transfer mechanism; it's the transfer mechanism which will
require the lock. More sigificantly, once B has the copy, there
is no need for a lock in order to use it, since nothing is
shared with the original. If CoW is being used, then some types
of access (most, given the semantics of std::string) must be
locked. Typically, internally in the implementation of
std::string, since the sharing is supposed to be transparent to
the client code.
I assume that thread A sees some string that is owned by B,
and then goes and assigns it to that string. Let's assume the
string uses a deep-copy.
If more than one thread is accessing the same string object,
and any thread is modifying it, all threads need to synchronize.
Nothing changes here---that's the same rule as for int, and
affects CoW and other implementations equally.
If two threads are accessing different string objects, however,
where one was originally a copy of the other, you don't expect
to have to lock. With CoW, however, the two string objects
actually share a single internal object containing the
representation, so some sort of locking is required in the
string class itself.
If *during* that deep-copying thread B starts reading the
string, it will get incorrect data (because it has only been
partially copied).
The other possibility I can think of is that thread B makes
the copy. In other words, it sees the string owned by thread
A, and assigns it to its own string.
Again: If thread A goes and modifies its string while this
deep-copying is happening, the data which is copied to B will
become corrupted.
I just can't see how deep-copying solves any synchronization
problems.
It means that all cases where a single object is accessed by
more than one thread, and modified by at least one thread, are
visible to the client (who is responsible for locking in such
cases). With CoW, there is a hidden object, which may be
accessed from different threads without the client code seeing
it, so the string class itself must assume the responsibility
for locking.
The only way to copy the string from A to B safely is to lock
access to it for the duration of the copying (regardless of
how the copying is done). I can't see any other way.
That's not the issue. The issue is what happens once you've
made the copy, when you're using one string object in thread A,
and a completely different string object in B.