 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Vladimir Frolov Guest
|
Posted: Thu Dec 29, 2005 12:15 pm Post subject: Using local static variables within concurrent environment. |
|
|
Hello,
I have found problem using local static variable within concurrent
environment. Undefined behavior can be caused not only by recursive
control
re-entering the declaration of local static variable (as it is
specified in
standard, see [stmt.dcl]) but also concurrence control re-entering.
int foo(int i)
{
static int s = foo(2*i); // recursive call cause undefined behavior
return i+1;
}
const std::string& f1()
{
static const std::string string_data("data");
// undefined behavior if f1() will be invoked concurrently for the
first
time
return string_data;
}
const std::string string_global_data("global_data");
const std::string& f2()
{
// Ok. f2() can be invoked concurrently
return string_global_data;
}
One has to note that function f1() unlike f2() cannot be invoked
concurrently because construction of string_data object will be done
without
any synchronization, and constructor of std::string can be invoked
concurrently several times before string_data will be marked as
constructed.
It means that Meyers singleton cannot be used on concurrent environment
without additional non-trivial synchronization as well.
Thanks.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Sat Dec 31, 2005 1:38 pm Post subject: Re: Using local static variables within concurrent environme |
|
|
Vladimir Frolov wrote:
| Quote: | I have found problem using local static variable within
concurrent environment. Undefined behavior can be caused not
only by recursive control re-entering the declaration of local
static variable (as it is specified in standard, see
[stmt.dcl]) but also concurrence control re-entering.
int foo(int i)
{
static int s = foo(2*i); // recursive call cause undefined behavior
return i+1;
}
const std::string& f1()
{
static const std::string string_data("data");
// undefined behavior if f1() will be invoked concurrently for the
first
time
return string_data;
}
const std::string string_global_data("global_data");
const std::string& f2()
{
// Ok. f2() can be invoked concurrently
return string_global_data;
}
One has to note that function f1() unlike f2() cannot be
invoked concurrently because construction of string_data
object will be done without any synchronization, and
constructor of std::string can be invoked concurrently several
times before string_data will be marked as constructed.
|
The standard doesn't say anything about this, since it ignores
threading. So it depends on what your implementation
guarantees. I think that most implementations do make no
guarantees, however, so it is up to you to ensure external
synchronization.
As a general rule, static data in a multithreaded environment is
an invitation to problems. There are different ways of
mitigating the problem; in cases like the above, for example,
using a char const[], rather than string, sidesteps all
potential problems.
| Quote: | It means that Meyers singleton cannot be used on concurrent
environment without additional non-trivial synchronization as
well.
|
I'm not sure what you mean by "Meyers singleton"; in the last
article I read by Scott Meyers concerning singletons, he
explicitly treated this problem. The synchronization is fairly
trivial from a programmer's point of view, although it has some
runtime cost. You can reduce the cost significantly by using
platform specific atomic access mechanisms, but at least in some
cases (e.g. Sun CC under Solaris) they require inline assembler.
Or you can just ensure that the singleton is instantiated before
threading is started -- in my own code, I require as an absolute
precondition that no additional threads are started before
entering main, and I use something like:
Singleton* Singleton::ourInstance = Singleton::instance() ;
Singleton*
Singleton::instance()
{
if ( ourInstance == NULL ) {
ourInstance = new Singleton ;
}
return ourInstance ;
}
(Both ourInstance and instance() are static members of
Singleton, obviously.)
This ensures that Singleton::instance() is called at least once
during static initialization, i.e. before entering main.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Axter Guest
|
Posted: Sat Dec 31, 2005 7:24 pm Post subject: Re: Using local static variables within concurrent environme |
|
|
Vladimir Frolov wrote:
| Quote: | Hello,
I have found problem using local static variable within concurrent
environment. Undefined behavior can be caused not only by recursive
control
re-entering the declaration of local static variable (as it is
specified in
standard, see [stmt.dcl]) but also concurrence control re-entering.
const std::string string_global_data("global_data");
const std::string& f2()
{
// Ok. f2() can be invoked concurrently
return string_global_data;
}
One has to note that function f1() unlike f2() cannot be invoked
concurrently
|
f2() unlike f1() produces undefined behavior when called from multiple
translation units before main() gets called.
In other words, if another global object located in a different
translation unit calls f2(), (IAW C++ Standard) there is no garantee
that global object string_global_data has been initialize. There's no
garanteed method for the order of initialization of global complex
objects located in different translation units.
It's far more likely that a singleton will run into this problem, then
it would be likely to have concurrent problem.
If you do have concurrent logic, then I would recommend removing the
concurrent logic in order to safely create the singleton.
But I would not recommend using a global variable.
Using a local static variable is much safer, and gives you more defined
behavior.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ul Guest
|
|
| Back to top |
|
 |
Axter Guest
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|