Multithreading Design, protect global member in C++ - c++

I am writing a c++ app with QT, with a focus at speed optimization.
I want to have a few global objects with read only access for different threads.
Before I open the threads, I have to initialize the global objects and fill them with data.
How I can protect the set functions of my Global Objects, but still have access from the main function?
Example code like it is now:
myClass.h
class MyObjectClass {
public:
void SetSome(const QList<QString> &value);
QList<QString> GetSome() const;
private:
QList<QString> m_myMember;
};
main.cpp
#include "global.h" // some like: extern MyObjectClass g_InihalizedInMain;
#include "anyThread.h"
int main(){
g_InitializedInMain.SetSome() // This Shut work
MyThread thread;
thread.start();
//..
return 0;
}
anyThread.cpp:
#include "global.h"
void thread::run()
{
MyObjectClass newObject = g_InihalizedInMain; //This shut work
g_InitializedInMain.GetSome(); //This shut work
g_InitializedInMain.SetSome(); //This shut not work and give me an error during compile time
newObject.SetSome(); //This shut work
}
I would be happy if you have a few design ideas for me, thanks a lot!

class MyPrivateObjectClass : private MyObjectClass
{
public:
friend void main();
};
extern MyPrivateObjectClass g_InitializedInMain;

Make your global variable static which means only the one source file can access it. You can then provide accessor functions that can read the data from other threads.

For starters, I would try to avoid global variables at all costs.
What you could do instead of global variables is to instantiate a variable in main (either
dynamically, or locally on the stack, depending on your preferences)
and set it in the thread object (this is called dependency injection)
To control setting attributes on MyObjectClass only from main, I can think of 2 options:
Set all of the MyObjectClass attributes via the constructor in main, thus allowing you to remove the setters, but leave the getters. The MyObjectClass would be immutable.
Create a context object that contains all the settable attributes for MyObjectClass. This context object can only be passed into the MyObjectClass constructor. The context object should be created in main, calling the appropriate setters, then passed into MyObjectClass upon instantiation from main. The MyObjectClass class uses these attributes from the context object internally, but doesnt have setters for them. There would of course be getters available on MyObjectClass, that would get the values from the internal context object. The MyObjectClass would be immutable, but this way is a bit more flexible.
I prefer the second option. Here is a code sample:
myClass.h
class MyObjectContext {
public:
void SetSome(const QList<QString> &value);
QList<QString> GetSome() const;
private:
QList<QString> m_myMember;
};
class MyObjectClass {
public:
MyObjectClass(MyObjectContext *context) : context_(context) {}
QList<QString> GetSome() const {return context_->GetSome();}
// Put the rest of the important stuff here
private:
MyObjectContext *context_;
MyObjectClass(); // explicitly stating that the default ctor cant be called
};
main.cpp
int main(){
// creating these objects on the stack, you may need
// to create them dynamically, its up to you
MyObjectContext context;
context.SetSome() // This Should work
MyObjectClass moc(&context);
MyThread thread(&moc);
thread.start();
//..
return 0;
}
anyThread.h
class MyThread : public QThread { // Assuming you're inheriting from QThread
public:
// instead of setting it via the ctor, you could consider adding a setter
MyThread(MyObjectClass *moc) : moc_(moc) {}
void run();
private:
MyThread(); // explicitly stating that the default ctor cant be called
MyObjecctClass *moc_
};
anyThread.cpp
void MyThread::run()
{
moc_->GetSome(); //This should work
// Dont have to worry about the setters, since there are none
// available for the MyObjectClass, which is now immutable
}

Related

QRunnable emit signal and get sender from slot

QRunnable is destroyed by QThreadPool after it finishes. When I emit a signal from it and try to get the QRunnable object from slot using sender() it's NULL.
Minimal example:
// class MyRunnable : public QObject, public QRunnable
MyRunnable::run()
{
//... do some work
emit onFinished();
}
// constructor by request
MyRunnable::MyRunnable(QObject *parent) : QObject(parent),
m_someData(1),
{
}
...
private slots:
void onFinished()
{
MyRunnable* myRunnable = qobject_cast<MyRunnable*>(sender());
int val = myRunnable->getSomething(); // myRunnable is null and it crashes
}
...
// later I start it using some thread pool
MyRunnable* myRunnable = new MyRunnable;
connect(myRunnable, SIGNAL(onFinished()), this, SLOT(onFinished());
threadPool.start(myRunnable);
Is there any way I can specify when to delete this object? So I can safely access it's data members inside my slot?
You want to access your object's members after it has been destroyed. Obviously, you can't safely do that.
Plus, casting sender() to access it directly is a danger sign - both in terms of unnecessary coupling and in terms of thread safety.
Instead, you probably want to copy the relevant members into the signal:
MyRunnable::run()
{
//... do some work
emit onFinished(getSomething());
}
and simply use the results in the listener.
If you really believe you must control the lifetime of the runnable, you could observe that
the thread pool takes ownership of the runnable if runnable->autoDelete() returns true
So you could override autoDelete() to return false, then call its deleteLater() method from your slot. Take care accessing its members directly, as it is still an a thread-pool thread.
The runnable is processing a request and producing a response. Factor those out and the problem is solved:
struct FooRequest;
struct FooResponse;
using FooResponsePtr = std::shared_ptr<FooResponse>;
class Foo : public QObject, public QRunnable {
FooRequest m_req;
protected:
void run() override {
std::shared_ptr<FooResponse> rsp;
/* ... */
emit hasResponse(rsp);
}
public:
Foo(const FooRequest & req) : m_req(req) {}
Foo(FooRequest && req) : m_req(std::move(req)) {}
Q_SIGNAL void hasResponse(const FooResponsePtr &);
static void main() {
qRegisterMetatype<FooResponsePtr>();
}
};
Q_DECLARE_METATYPE(FooResponsePtr)
int main() {
Foo::main();
...
};
You could also make FooResponse an explicitly shared class using QExplicitlySharedDataPointer, making it like other cheap-to-copy Qt value classes. The access would then be direct, without a need for std::shared_ptr. The explicit sharing is cheaper than implicit sharing, and makes more sense if you don't intend to retain the copy-on-write behavior of implicit sharing.

Setup static member object

Maybe this question has been asked around but I couldn't find it. How do I setup a static member object at its creation? And possibly perform some other tasks. The goal is to have some of it's setters called at it's creation time.
Example:
Header file A.h:
class A{
public:
A::A();
~A::A();
static QTimer updateTimer;
};
Expected implementation file A.cpp:
#include "A.h"
QTimer A::updateTimer.setInverval(100); // I need to set it's inverval to 100ms
// but only once in the beginning of it's life time
A::A(){...
}
~A::A(){...
}
So, as you can see, I would like to call 'setInverval()' function of my static object only once at it's creation and not have it called every time a new 'A' object is created.
This is what constructors are for.
If it's your own type, just write a constructor.
If the type doesn't have a constructor and you cannot modify it (like, presumably QTimer comes from Qt), then wrap it in a type of your own that does. This is a textbook case of inheritance being useful. Your wrapper class will extend the original class with a bit of new functionality: setting the interval during initialisation.
struct QTimerWrapper : QTimer
{
QTimerWrapper(int interval)
{
setInterval(interval);
}
};
struct A
{
static QTimerWrapper updateTimer;
};
QTimerWrapper A::updateTimer(100);
Or you could use composition, having the QTimer be a member of QTimerWrapper instead.
In addition to composition or inheritance, you can also create a function which returns the modified object
QTimer newTimerWithInterval(int interval){
QTimer timer;
timer.setInteval(interval);
return timer;
}
QTimer A::updateTimer(newTimerWithInterval(100));
You might want to put the function under local namespace as you do not probably need it anywhere else.
maybe something like this? pseudocode:
class A { static shared_ptr<Timer> _timer; };
..
A::A()
{
if (_timer == nullptr)
{
_timer.assign(new Timer);
_timer->setInterval(100);
}
}
or if you don't need to manage this timer or have any dynamic objects - then you can use statically made inner object:
class A { /* without static member */ };
A::A
{
static bool timerInited = false;
static QTimer timer;
if (!timerInited)
{
timer.setInterval(100);
timerInited = true;
}
}

QTimer::SingleShot fired after object is deleted

// Example class
class A : public QObject
{
Q_OBJECT
void fun() {
Timer::SingleShot(10, timerSlot); //rough code
}
public slot:
void timerSlot();
}
auto a = SharedPointer<A>(new A);
a->fun();
a->reset(); // a deleted
In this case after a is deleted and timer is fired, would it execute timerSlot()? I'm getting an extremely rare crash and not sure if it's because of something fishy in this logic.
Even if the timer fires, it won't trigger the slot. The docs of ~QObject state: All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue. The only way you can trigger the A::timerSlot and delete A at the same time is if you use threads.
You are not obligated to disconnect an object's signals and slots before deleting it.
The QObject destructor will clean up obsolete signal-slot connection for you, as long as you:
Inherit from QObject
Use the Q_OBJECT macro in your class definition
Following these conventions ensures that your object emits a destroyed() signal when deleted. That's actually what Qt's signals-and-slots system uses to clean up dangling references.
You can listen to the destroyed() signal yourself if you'd like to add some debugging code to track object lifecycles.
(Depending on the particular version of Qt/moc you are using, it's quite possible that code with a non-QObject using slots, or a QObject-derived class that doesn't have Q_OBJECT in its header will still compile but cause the timerSlot() method to be invoked on a garbage pointer at runtime.)
I'm getting a extremely rare crash due to timer out of object scope which I need to fire just once. I use QTimer::singleShot which is static method and does not pertain to an instance of QTimer object which I would release with the context it fires the signal to.
That is of course solved in QTimer class and desired behavior controlled by the instance of timer class with non-static QTimer::singleShot property set to true.
// declaration
QScopedPointer<QTimer> m_timer;
protected slots:
void onTimeout();
// usage
m_timer.reset(new QTimer);
m_timer->setSingleShot(true);
QObject::connect(m_timer.data(), SIGNAL(timeout()), this, SLOT(onTimeout()));
m_timer->start(requiredTimeout);
So, no crash should happen due to timer released with the context object.
Edit: This answer was in response to the original question which did not use QObject but had class A as a standalone class inheriting nothing. The question was later edited making this answer obsolete, but I'll leave it here to show what would be needed if not using QObject.
The only way you can do that is if you keep the object alive until the timer has fired. For example:
class A : enable_shared_from_this<A> {
void fun() {
QTimer::singleShot(10, bind(&A::timerSlot, shared_from_this()));
}
public:
void timerSlot();
}
auto a = SharedPointer<A>(new A);
a->fun();
a->reset(); // a goes out of scope, but its referent is kept alive by the `QTimer`.
The reason the above works is that you capture a shared_ptr to class A when setting the timer, and the timer will hold onto it (else it can't fire).
If you don't like or can't use recent C++ features or Boost:
struct Functor {
Functor(SharedPointer<A> a) : _a(a) {}
void operator() { a->timerSlot(); }
SharedPointer _a;
};
class A {
void fun(shared_ptr<A> self) {
QTimer::singleShot(10, Functor(self));
}
public:
void timerSlot();
}
auto a = SharedPointer<A>(new A);
a->fun(a);
To reach certainty, you can stop the timer yourself:
class A : public QObject {
QTimer t;
A() { connect(Signal-Slots); }
~A() { t.stop(); }
fun() { t.start(10); }
...
};

Safety using entity from different part of program

I have several modules in my program (e.g. Database, Scheduler) which uses same entity - some game server.
Main goal is that each module uses game server API with limited functionality (functionality which need for interaction between separate module and game server only) and other functions must be hide.
I have created such functionality. But I don't now, maybe it's wrong realization or maybe somebody guess better method.
Class which placed below contain some operations which can be access only from others modules via classes wrappers.
#ifndef _GAMESERVER_
#define _GAMESERVER_
#include <vector>
class GameServer
{
static GameServer instance;
std::vector<int> game_actions;
GameServer(){}
~GameServer(){}
GameServer(const GameServer&){}
protected:
void addGameAction(int action) // Some functionality, which can be accessible only from others modules via classes wrapers
{
game_actions.push_back(action);
}
public:
static GameServer *getInstance()
{
return &instance;
}
bool start()
{
return true;
}
void stop()
{
}
};
#endif
Below placed class 'wrapper' for class GameServer which has been realising API for interaction with module Database.
#ifndef _DBGAMESERVER_
#define _DBGAMESERVER_
/* Database module will use this API for interacting with game server */
class GameServer;
class DBGameServer : protected GameServer
{
DBGameServer();
public:
static DBGameServer *getInstance()
{
return static_cast<DBGameServer *>(GameServer::getInstance());
}
void addGameAction(int action)
{
GameServer::addGameAction(action);
}
};
#endif
Thanks!
You are creating your singleton instance at first call to getIntance. It may be unsafe in a multithreaded application : race conditions could lead to multiple instances being actually intialized and used.
IMHO you would better use static initialization :
Declaration :
...
class GameServer {
static GameServer& instance;
// private constructor, copie constructor and destructor
...
public:
static GameServer * getInstance() { return &instance; }
...
}
Implementation :
...
GameServer & GameServer::instance = GameServer();
...
That way you are sure that the object is constructed only once during program start (before first instruction), and destructor is called at program end (after last instruction). Of course if constructor throws an exception the program will stop abruptly before it is given any chance to display anything : the eventual error messages should be displayed inside constructor.

C++ Creating Global Reference of an Object

I am trying to create a global reference of an object but it seems fails or I am getting another error in Qt C++.
I have a class called 'System' which holds many objects as members. I want to access System's members from everywhere include members of System. Here is my code below:
// System.h
class System
{
public:
Obj1* m_obj1;
Obj2* m_obj2;
System();
~System();
static System* GetGlobalReference();
}
// System.cpp
static System* GlobalReference = 0;
System::System()
{
if (!GlobalReference) GlobalReference = this;
m_obj1 = new Obj1();
m_obj2 = new Obj2();
}
System* System::GetGlobalReference()
{
return GlobalReference;
}
// main.cpp
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
System* system = new System();
MainWindow window;
window.showMaximized();
return app.exec();
}
//Obj1.h
class Obj1 : public QObject
{
Q_OBJECT
public:
Obj1() : QObject() {}
~Obj1();
public slots:
void Import();
}
// Obj1.cpp
void Obj1::Import()
{
QString path = QFileDialog::getOpenFileName(
0,
QString("Import file..."),
QString("C:\\"),
QString("JPEG File (*.jpg)"),
0,
0);
if (System::GetGlobalReference())
System::GetGlobalReference()->m_obj2->Import(path); // error here
else
// System::GlobalReference is null
}
It seems reference is not null but I get an error during runtime "Access violation reading location..." What is wrong?
Btw Obj1 is a QObject and Import method is a public slot, can the error be related with this?
Edit: Debuugger last step is here in QGenericAtomic.h
T load(const T &_q_value) Q_DECL_NOTHROW
{
return _q_value; // -> Debugger stops here
}
Edit2: I've used Singleton pattern as the answers says but my problem still continues.
System::GetInstance()->GetObj1()->Import(path); // after this line
in "_q_value" it says ""
If you wish to have global variables, I would recommend using a singleton instead.
Global variables in C++ are declared using extern, not static. See the reference for more information.
If you want only one instance of your System class, you should use the Singleton pattern.
But, the Singleton pattern should be used when you want an unique instance of a class, the reason should not be when you want to have an object global. Even if using this pattern, your instance is accessible from everywhere.
Look at this article about Singleton design pattern, it may be useful in your case.
Also, in C++ the declaration of global variable is done with extern, not static.
I've solved my problem. The problem was caused by Obj1->Import method but during debug in qt, debugger is not accessing inside the method when I press F11(Step Into). I cannot figure it out why?