
Hello Sohail, Tuesday, February 6, 2007, 1:34:50 AM, you wrote:
Hi Andrey,
Tuesday, February 6, 2007, 1:08:25 AM, you wrote:
Is there interest in having a boost singleton? A preliminary implementation of it could use boost::once. Then all lazy initializations would happen through that interface.
Just a thought.
I think a generic implementation of a thread-safe singleton is a nice idea. I encounter this problem quite often. Although, once-based implementation doesn't suit me very well in this case.
What kind of solutions have you come up with for lazily initializing singletons in a thread-safe manner?
In most cases I tried not to create the singleton lazily but initialize it as soon as possible. The perfect time is on executable module load which, AFAIK, is always done in single thread on platforms I have faced yet. Such approach was quite sufficient for me since it solves the key problem of the singleton creation. And the created singleton may be not fully initialized at first, i.e. it may not acquire significant system resources on construction but may do so on first requests to it. Such requests are easy to synchronize since the singleton with a mutex already exists. Maybe a similar approach in a generic implementation of a lazy singleton worth considering too. I mean, on module load the implementation may safely construct a mutex and a null reference to a yet non-exiting singleton instance (see Alexandrescu's implementation with dead reference detection). This would let you to synchronize later when the instance is requested first time and needs to be created. And the very same mutex may be used by the singleton later for its own needs. The problem is that I guess not every compiler/platform would let you to hook into the module load sequence. For those configurations we might fall back to once-based implementation.
What are your reasons for not preferring a boost::once implementation? I can only think of boost::once based or platform specific, which scares me, to be frank!
In the Boost.FSM lib boost::call_once is not very desirable because that lib is intended to be light. It may even be used without threading at all (and in fact, this is expected to be the major domain of use). So I cannot force users to build Boost.Thread just to support the internals of the header-only library. The same disadvantage would be in case of the generic singleton implementation. I believe that such implementation should provide a way to create singletons without requiring building any libraries in single-thread and even in multi-thread environment, where possible. Maybe if there was some lightweght_call_once somewhere in Boost the problem would be solved.
The solution to the problem seems to be a function of hardware and OS primitives which (I thought) pthread_once/family solve as nicely as you'd want.
Pthreads are quite widespread but not ultimate. At least win32 threading needs to be supported too.
Personally, I'm fairly new to the whole multi-proc scene so I'd really appreciate some enlightenment!
I'm no expert too. Let's hope that someone who really knows the field is reading this. -- Best regards, Andrey mailto:andysem@mail.ru