singleton with multithreading

A

ank

Hi,
I have some question about Singleton Pattern in C++.

I think I understand that static initialization order across
translation unit
is unspecified by the standard, but what can I do to ensure that some
kind of
static mutex is automatically initialized before the first use of it?

I cannot assume that this mutex is used only after executing main()
function because I need to use this mutex to lock singleton inside
initialization code and may apply double-check pattern.

Currently, I have very little experience with multithread programming.
I am not a native English speaker so my message may not be well
written.

Thanks in advance for any suggestions.
 
M

Maxim Yegorushkin

Hi,
I have some question about Singleton Pattern in C++.

I think I understand that static initialization order across
translation unit
is unspecified by the standard, but what can I do to ensure that some
kind of
static mutex is automatically initialized before the first use of it?

To force initialization without dependency on module initialization order
you may employ schwarz counter idiom (google groups for it). This is how
standard streams (std::cout, etc) get initialized.
 
A

ank

Which means I have to include the initialization code in every module
that
use my service.
Am I right?
 
M

Maxim Yegorushkin

Which means I have to include the initialization code in every module
that use my service.
Am I right?

Only the code that calls your initialization code at the proper moment.
The initialization code can be in any translation unit you like.
 
A

ank

Maxim said:
Only the code that calls your initialization code at the proper moment.
The initialization code can be in any translation unit you like.

Thanks for your suggestion Maxim, I think it is the reasonable thing to
do to deal with the problem.

I think I can use the counter to help initialize mutex before any code
that acquire lock with it and all is done, in thread-safe fashion.
This technique don't suffer from threading issue because you have no
way use the object before the counter is initialized, by any
global/static external object, in any thread, right?.

Is Schwarz counter efficient enough
or is it best to use non-portable compiler option?
I want to know other's opinion.
 
M

Maxim Yegorushkin

Maxim said:
Only the code that calls your initialization code at the proper moment.
The initialization code can be in any translation unit you like.
[]

I think I can use the counter to help initialize mutex before any code
that acquire lock with it and all is done, in thread-safe fashion.
This technique don't suffer from threading issue because you have no
way use the object before the counter is initialized, by any
global/static external object, in any thread, right?.

Right. By the time you use it it has already been initialized.
 
J

Joe Seigh

ank said:
Hi,
I have some question about Singleton Pattern in C++.

I think I understand that static initialization order across
translation unit
is unspecified by the standard, but what can I do to ensure that some
kind of
static mutex is automatically initialized before the first use of it?

I cannot assume that this mutex is used only after executing main()
function because I need to use this mutex to lock singleton inside
initialization code and may apply double-check pattern.

Currently, I have very little experience with multithread programming.
I am not a native English speaker so my message may not be well
written.

Thanks in advance for any suggestions.

Well for starts, read this
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
This may kick off one of those interminable discussions where about half
of the participants will never get it.

To summarize, DCL isn't actually broken, it just that there aren't any
portable mechanisms to implement it correctly on all platforms. The
naive implementation using pointers assumes dependent load ordering. You
have to know which platforms this works on. It doesn't work on Alpha
processors.

There are design patterns let you implement DCL correctly. One is to have
each thread use a thread local variable whether it has a properly synchronized
view of the singleton data. The other is to only access the singleton via
a object of that class which has been properly synchronized with the singleton
in its construction. Access to the objects is assumed to be properly synchronized
also.

Initialization of a Posix pthread mutex is
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

For windows you can use a named Mutex which can be dynamically initialized in
a thread-safe manner. Windows CriticalSection initialization isn't thread-safe.
You can use compare and swap to initialize a CriticalSection. Example of this
here in the initFreeQueue subroutine. It also uses the access via object technique.
http://groups.google.com/groups?q=g...r=&ie=UTF-8&[email protected]


I'd stay away of any naive spinlock implementations. Not only are they inefficient but
they're likely to be incorrect with regard to proper memory visibility, i.e. missing
necessary memory barriers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,296
Messages
2,571,535
Members
48,281
Latest member
DaneLxa72

Latest Threads

Top