0

I'm making use of thread-safe QObject singletons in my own project and I was wondering whether I'm doing right in creating them using QtConcurrent rather than QMutex'es and QThread's.

Here is how I'm managing to write singleton code.

class A : public QObject
{
 Q_OBJECT
 public:
         A() {}
         static A* sharedInstance() {
             static QFuture<A*> helper = QtConcurrent::run([]() -> A* {
                 auto *instance = new A();
                 instance->moveToThread(qApp->thread());
                 return instance;
             });
             return (A*)helper;
         }
 };

Is this any way better than the following?

class A : public QObject
{
 Q_OBJECT
 public:
         A() {}
         static A* sharedInstance() {
             static A* instance = 0;
             static QMutex mtx;
             mtx.lock();
             if (!instance) {
                instance = new A();
                instance->moveToThread(qApp->thread());
             }
             mtx.unlock();
             return instance;
         }
 };

Or, is there any other better way of doing this?

Thank you.

NOTE: I'm handling the shared instance destruction separately.

EDIT: I want the shared instances to be in the main thread.

alediaferia
  • 2,537
  • 19
  • 22

1 Answers1

0

The two pieces of code do very different things. The first one constructs the new instance in a worker thread, then moves it to the main thread. This is done while the calling thread blocks for the new instance to be created. I have no idea why would you do that, since it buys you absolutely nothing besides complication. The calling thread blocks no less than if you had constructed the instance in the calling thread. It also has nothing to do with singletons: The sharedInstance will return a new instance on every invocation.

The second one constructs the instance in whatever thread happens to first access sharedInstance from. You'd need to tell us what you mean by "thread safe singletons". Since QObject can be directly accessed from one and only one thread only, I don't quite get why you need a thread-safe singleton QObject.

Anyway, the second variant is just reinventing Q_GLOBAL_STATIC for seemingly no reason at all.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I'm editing my question: having the instance in the main thread is a requirement for me. For the first piece of code, I think the `static QFuture` will make the lambda run only once. This way further accessess to the shared instance will not involve mutex locking. The second block, instead, involves mutex locking for every access. Am I completely wrong? – alediaferia Jun 07 '14 at 07:31