Discussion:
Thread safe STL for VC6.0
(too old to reply)
Faisal
2008-06-03 05:01:19 UTC
Permalink
Hi,

My application developed with VC6.0 crashes in multiprocessor
machines. On initial analysis, I found that STL string class which is
not thread safe is causing this problem.

http://support.microsoft.com/kb/813810

Is there any fix available for this problem in VC6.0? Does this
problem occur only for string or other stl classes like list,vector
etc.

Does anybody know about some thread safe STL library which can be used
with VC6.0?

regards,
FM
Doug Harrison [MVP]
2008-06-03 05:23:41 UTC
Permalink
Post by Faisal
Hi,
My application developed with VC6.0 crashes in multiprocessor
machines. On initial analysis, I found that STL string class which is
not thread safe is causing this problem.
http://support.microsoft.com/kb/813810
Is there any fix available for this problem in VC6.0? Does this
problem occur only for string or other stl classes like list,vector
etc.
See:

http://www.dinkumware.com/vc_fixes.html
Post by Faisal
Does anybody know about some thread safe STL library which can be used
with VC6.0?
Maybe STLport. See also the Express Edition of VC 2008; it doesn't have
everything the paid versions have, but who knows, it may meet your needs.
--
Doug Harrison
Visual C++ MVP
Faisal
2008-06-03 05:37:52 UTC
Permalink
Post by Doug Harrison [MVP]
Post by Faisal
Hi,
My application developed with VC6.0 crashes in multiprocessor
machines. On initial analysis, I found that STL string class which is
not thread safe is causing this problem.
http://support.microsoft.com/kb/813810
Is there any fix available for this problem in VC6.0? Does this
problem occur only for string or other stl classes like list,vector
etc.
http://www.dinkumware.com/vc_fixes.html
In this link, they says even with this fixes the string is not thread
safe.
Post by Doug Harrison [MVP]
Post by Faisal
Does anybody know about some thread safe STL library which can be used
with VC6.0?
Maybe STLport. See also the Express Edition of VC 2008; it doesn't have
everything the paid versions have, but who knows, it may meet your needs.
--
Doug Harrison
Visual C++ MVP
Ismo Salonen
2008-06-03 08:35:58 UTC
Permalink
--snip--

Reading a little bit more tells how to really fix this issue:

Another way is to disable reference-counting altogether, making string
operations thread safe. Simply change the value of _FROZEN to zero:

enum _Mref {_FROZEN = 255}; // set to zero to disable sharing


br
ismo
Faisal
2008-06-11 06:55:05 UTC
Permalink
Post by Ismo Salonen
--snip--
Another way is to disable reference-counting altogether, making string
enum _Mref {_FROZEN = 255}; // set to zero to disable sharing
br
ismo
I resolved my problem by changing _FROZEN to zero. By making the
_FROZEN to zero I'm disabling the memory sharing mechanism of string.
right?. So my application would take more size with this workaround.

In Microsoft site, they suggest to move to VC7.0 or later for
completely resolving this issue. In VC7.0 and later whether Microsoft
fixed this issue by disabling the memory sharing or providing some
thread safe reference counting?

I would like to know If I switch to VC7.0 or later, will my
application work with lesser memory( by memory sharing mechanism )? If
It wont, I can go with VC6.0 work around.
Joe Greer
2008-06-11 13:59:27 UTC
Permalink
Post by Faisal
Post by Ismo Salonen
--snip--
Another way is to disable reference-counting altogether, making string
enum _Mref {_FROZEN = 255}; // set to zero to disable sharing
br
ismo
I resolved my problem by changing _FROZEN to zero. By making the
_FROZEN to zero I'm disabling the memory sharing mechanism of string.
right?. So my application would take more size with this workaround.
In Microsoft site, they suggest to move to VC7.0 or later for
completely resolving this issue. In VC7.0 and later whether Microsoft
fixed this issue by disabling the memory sharing or providing some
thread safe reference counting?
I would like to know If I switch to VC7.0 or later, will my
application work with lesser memory( by memory sharing mechanism )? If
It wont, I can go with VC6.0 work around.
If I remember right, they don't do reference counted strings (shared), but
they do have the short string optimization. So, what that generally means
is that if you have a lot of short strings (under 16 characters) you will
probably use less memory, but if your strings are longer then you may use
more. You will have to try it and measure to be sure.

joe
Stephen Howe
2008-06-12 10:47:24 UTC
Permalink
Post by Faisal
In Microsoft site, they suggest to move to VC7.0 or later for
completely resolving this issue. In VC7.0 and later whether Microsoft
fixed this issue by disabling the memory sharing or providing some
thread safe reference counting?
They disabled the memory sharing.
The C++ portions of Microsoft's stuff are all by Dinkumware.
Dinkumware also provide VC6.0 patches they never made it into any Service
Pack.
See here
http://www.dinkumware.com/vc_fixes.html

The memory sharing is commonly called COW strings (COW = copy-on-write).
As far as I know, all C++ vendors have moved away from COW strings because
it is extremely difficult to have both COW and thread safety.
If you do make them thread-safe (and Herb Sutter explores these options in
Exception C++ style), they are slow.
Nobody supplies COW strings these days because of the issues involved.
The C++ community has moved away from them.
Post by Faisal
I would like to know If I switch to VC7.0 or later, will my
application work with lesser memory( by memory sharing mechanism )? If
It wont, I can go with VC6.0 work around.
I would not think about. I would move to a later version (we did).
VC 7.1 and later are so much more C++ compliant that we would not think of
using VC6.0 again.

The only issue which is not widely advertised, is that later versions of VC
produce executables that wont run on earlier versions of Win32 OS's.

Stephen Howe
Faisal
2008-06-12 12:34:24 UTC
Permalink
On Jun 12, 3:47 pm, "Stephen Howe" <stephenPOINThoweATtns-
Post by Stephen Howe
Post by Faisal
In Microsoft site, they suggest to move to VC7.0 or later for
completely resolving this issue. In VC7.0 and later whether Microsoft
fixed this issue by disabling the memory sharing or providing some
thread safe reference counting?
They disabled the memory sharing.
The C++ portions of Microsoft's stuff are all by Dinkumware.
Dinkumware also provide VC6.0 patches they never made it into any Service
Pack.
See herehttp://www.dinkumware.com/vc_fixes.html
The memory sharing is commonly called COW strings (COW = copy-on-write).
As far as I know, all C++ vendors have moved away from COW strings because
it is extremely difficult to have both COW and thread safety.
But still MFC CString class uses this reference counting and they are
thread safe too. right?
Post by Stephen Howe
If you do make them thread-safe (and Herb Sutter explores these options in
Exception C++ style), they are slow.
Nobody supplies COW strings these days because of the issues involved.
The C++ community has moved away from them.
Post by Faisal
I would like to know If I switch to VC7.0 or later, will my
application work with lesser memory( by memory sharing mechanism )? If
It wont, I can go with VC6.0 work around.
I would not think about. I would move to a later version (we did).
VC 7.1 and later are so much more C++ compliant that we would not think of
using VC6.0 again.
The only issue which is not widely advertised, is that later versions of VC
produce executables that wont run on earlier versions of Win32 OS's.
Stephen Howe
Stephen Howe
2008-06-12 13:53:51 UTC
Permalink
Post by Faisal
But still MFC CString class uses this reference counting and they are
thread safe too. right?
Reference Counting : It does for Visual C++ 6.0. I am not sure if that is
true for later versions.

Thread Safety:
They are thread safe at the class level and only with the programmers help.
It is possible to deliberately break CString
See
http://msdn.microsoft.com/en-us/library/aa300688(VS.60).aspx
Extract:
CString assists you in conserving memory space by allowing two strings
sharing the same value also to share the same buffer space. However, if you
attempt to change the contents of the buffer directly (not using MFC), you
can alter both strings unintentionally. CString provides two member
functions, CString::LockBuffer and CString::UnlockBuffer, to help you
protect your data. When you call LockBuffer, you create a copy of a string,
then set the reference count to -1, which "locks" the buffer. While the
buffer is locked, no other string can reference the data in that string, and
the locked string will not reference another string. By locking the string
in the buffer, you ensure that the string's exclusive hold on the data will
remain intact. When you have finished with the data, call UnlockBuffer to
reset the reference count to 1.
But you seem to be clinging to thread-safety like a lifebelt.
You realise that even if 2 objects are individually thread-safe, combined
they may not be.

If you had

CString husband;
CString wife;

and the contents of both are only supposed to be updated together, there is
nothing stopping a thread-switch after husband is updated.
Now a 2nd read reading both will have the wrong pair.

Also see
http://msdn.microsoft.com/en-us/library/h14y172e(VS.80).aspx

where it says
For size and performance reasons, MFC objects are not thread-safe at the
object level, only at the class level. This means that you can have two
separate threads manipulating two different CString objects, but not two
threads manipulating the same CString object. If you absolutely must have
multiple threads manipulating the same object, protect such access with
appropriate Win32 synchronization mechanisms, such as critical sections. For
more information about critical sections and other related objects, see
Synchronization in the Platform SDK.
The bottom line is you have to do some work yto make your application
thread-safe.
It is insufficient just to rely on components being thread-safe.

Stephen Howe
Doug Harrison [MVP]
2008-06-12 15:49:52 UTC
Permalink
Post by Faisal
On Jun 12, 3:47 pm, "Stephen Howe" <stephenPOINThoweATtns-
Post by Stephen Howe
Post by Faisal
In Microsoft site, they suggest to move to VC7.0 or later for
completely resolving this issue. In VC7.0 and later whether Microsoft
fixed this issue by disabling the memory sharing or providing some
thread safe reference counting?
They disabled the memory sharing.
The C++ portions of Microsoft's stuff are all by Dinkumware.
Dinkumware also provide VC6.0 patches they never made it into any Service
Pack.
See herehttp://www.dinkumware.com/vc_fixes.html
The memory sharing is commonly called COW strings (COW = copy-on-write).
As far as I know, all C++ vendors have moved away from COW strings because
it is extremely difficult to have both COW and thread safety.
The C++ Standard prohibits true COW by requiring basic_string::reference to
be a real reference instead of a proxy class. Most of the problems and
weird little rules about invalidation stem from this decision. But you're
right; no one uses the lame copy-just-in-case reference counting approach
that is allowed anymore.
Post by Faisal
But still MFC CString class uses this reference counting and they are
thread safe too. right?
More or less. See this post in the MFC group and the one it links to for
more on that:

http://groups.google.com/group/microsoft.public.vc.mfc/msg/adc8f8bd9637580c
--
Doug Harrison
Visual C++ MVP
Stephen Howe
2008-06-03 11:22:54 UTC
Permalink
Post by Faisal
Hi,
My application developed with VC6.0 crashes in multiprocessor
machines. On initial analysis, I found that STL string class which is
not thread safe is causing this problem.
http://support.microsoft.com/kb/813810
Is there any fix available for this problem in VC6.0?
(i) Well did you read the article?
You can change _FROZEN in xstring.

(ii) You could also try upgrading to a newer compiler.
VC6.0 is 10+ years old.
Visual Studio Express is free

(iii) You could try applying patches from Dinkumware.

(iv) have you applied SP5 (or SP6, I cannot remember)
Post by Faisal
Does this
problem occur only for string or other stl classes like list,vector
etc.
Yes problem occurs elsewhere. They are not thread safe.
Post by Faisal
Does anybody know about some thread safe STL library which can be used
with VC6.0?
You _DONT_ want a threadsafe STL library.
In itself, it is not good enough.
It operates at too fine a granularity to gain you anything. If you had

v.push_back(elem);
s = v.size();

while each operation push_back(), size() might be thread-safe, if you needed
both operations to be completed as a unit, STL's thread-safety gains you
_NOTHING_. An intervening thread could run between the two operations. A
mutex around both is what is needed. So if you require a mutex to guarantee
thread safety here, what has a thread-safe STL gained you? Nothing - except
slower operations.

It is _YOUR_ code that should ensure thread safety for any shared resources.

Stephen Howe
Ulrich Eckhardt
2008-06-03 12:15:13 UTC
Permalink
Post by Stephen Howe
You _DONT_ want a threadsafe STL library.
Right, you want a thread-safe implementation of the C++ standardlibrary.
What I mean is that STL is something different than the C++
standardlibrary, and thread-safety is still important...
Post by Stephen Howe
In itself, it is not good enough.
It operates at too fine a granularity to gain you anything. If you had
v.push_back(elem);
s = v.size();
while each operation push_back(), size() might be thread-safe, if you
needed both operations to be completed as a unit, STL's thread-safety
gains you _NOTHING_. An intervening thread could run between the two
operations. A mutex around both is what is needed. So if you require a
mutex to guarantee thread safety here, what has a thread-safe STL gained
you?
Wait: there are thread-safety guarantees that were made by e.g. the STL and
those are useful for the C++ standardlibrary, too. In particular that
concurrent read operations on an object don't interfere with each other is
an important point, and that is also guaranteed by any modern
implementation of the C++ stdlib (Note: I don't count the 10-year old one
that came with VC6 as modern).

Now, this thread-safety can only go so far, as you pointed out, I couldn't
read the main point from your example. I'd rather give a different example:

// If there is an element in the queue, handle that element
// now and then remove it from the queue.
if(!q.empty()) {
handle_element(q.front());
q.pop_front();
}

No possible implementation could make this work when there are concurrent
threads calling this code on the same queue. The reason is that 'empty()'
may itself run atomic but it can't guarantee that the queue is still
non-empty when executing the rest of the code. For that, indeed, you need
to guard access to the queue with a mutex or equivalent.

Uli
--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Stephen Howe
2008-06-03 17:35:30 UTC
Permalink
Post by Ulrich Eckhardt
Wait: there are thread-safety guarantees that were made by e.g. the STL and
those are useful for the C++ standardlibrary, too. In particular that
concurrent read operations on an object don't interfere with each other is
an important point, and that is also guaranteed by any modern
implementation of the C++ stdlib (Note: I don't count the 10-year old one
that came with VC6 as modern).
Are there? I dont believe there are any thread-safety guarantees for
standard C++, certainly not in original 1998 C++ standard, nor the 2003
update to the C++ standard. Point them out to me chapter and verse if so.
The standard is agnostic about threads.
There may be in the C++ 0x standard when it arrives.

Stephen Howe
Ulrich Eckhardt
2008-06-04 07:03:16 UTC
Permalink
Post by Stephen Howe
Post by Ulrich Eckhardt
Wait: there are thread-safety guarantees that were made by e.g. the STL
and those are useful for the C++ standardlibrary, too. In particular that
concurrent read operations on an object don't interfere with each other
is an important point, and that is also guaranteed by any modern
implementation of the C++ stdlib (Note: I don't count the 10-year old one
that came with VC6 as modern).
Are there? I dont believe there are any thread-safety guarantees for
standard C++, certainly not in original 1998 C++ standard, nor the 2003
update to the C++ standard. Point them out to me chapter and verse if so.
It's not the C++ standard that requires any guarantees about threading, but
implementations are actually aware of threads and some even manage to
document to what extent they are thread-safe.

Uli
--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
Jerry Coffin
2008-06-04 20:42:23 UTC
Permalink
In article <***@TK2MSFTNGP05.phx.gbl>, "Stephen Howe"
<stephenPOINThoweATtns-globalPOINTcom> says...

[ ... ]
Post by Stephen Howe
The standard is agnostic about threads.
There may be in the C++ 0x standard when it arrives.
Yes -- at least in the current draft, C++ 0x addresses threads, to at
least some extent. My understanding is that a couple of national bodies
have stated that they will vote against acceptance of a C++ standard
that does not address threading, so it seems extremely unlikely that
this would be removed.
--
Later,
Jerry.

The universe is a figment of its own imagination.
Loading...