is there any draw back of creating QProcess on the stack,
for something trivial like this
void Utils::changeFont()
{
QString command("book");
QStringList arguments({"opensans", "10"});
QProcess fontProcess;
fontProcess.start(command,arguments);
fontProcess.waitForFinished();
}
i have 10 Utils objects created;
Utils a , b , c .....,
the all call the Utils::changeFont() respectively.
would it be good for the process to be on the stack
i am asking because i have not seen it being used like this on any tutorial.
thanks
The issue here is not related to creating QProcess "on the stack". In fact, stack is a misnomer: what you're really asking is "can I create QProcess as a local variable". Yes, you can, of course!
But such a QProcess is useless, because you're not supposed to use the waitFor methods - not ever. They are a horrible API. Don't use them: instead, write asynchronous code - i.e. react to the signals indicated by the QProcess. In your case, all you need is to delete the object when the process is finished. Thus:
// Not a class!!
namespace Utils {
void changeFont()
{
QString command("book");
QStringList arguments({"opensans", "10"});
auto *fontProcess = new QProcess(context);
QObject::connect(fontProcess,
qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
fontProcess, &QProcess::deleteLater);
fontProcess->start(command,arguments);
}
}
Note that Utils shouldn't be a class - it's a terrible Java-ism. If you want to group utility functions in a namespace, use a namespace! That's what they are for :) The changeFont as presented shouldn't be a method, since it'd just become a static method, and at that point you don't need any state. If you need state, then the class needs to be way more specific than Utils - it may be e.g. a class that adapts QProcess to your particular uses, but it'd need to be very specific, otherwise you end up with deeply coupled spaghetti code.
In C++ there is almost never a reason to have Utils be a class. It's a typical red flag in code reviews. It needs to be a namespace, and if you actually need a class that keeps state, it must be a task-specific class that does one thing and does it well, and has no other functionality.
If you need to e.g. continue whatever work you were in the middle of once the process is finished, you should create a state machine and react to the state transition when the process is finished, and perform subsequent actions there. This way you'll also be explicit about what to do in case of errors. Such issues are plastered over when you write pseudo-synchronous code. If your code has any waitFor calls, it's basically broken - you just don't know it yet. Qt has done everyone a grave disservice for providing those pseudosynchronous methods. All they are good for is freezing the UI. Awful stuff if you care one bit about your user experience.
The example with new QProcess(parent) from the docs also assigns a parent QObject. You will need that (or another ownership strategy) if the process outlives the scope of the QProcess, which the example tacitly assumes.
In your case, you're calling waitForFinished() so it's fine if the QProcess gets deleted at the end of the function. There is no need for it to live longer.
That is ok, actually almost all examples in Qt documentation show creation of the QProcess on the stack.
The only drawback is the creation of the object itself. If you need it "rather often" maybe it would be better to create it once.
Related
I'm trying to expose a C interface for my C++ library. This notably involve functions that allow the user to create, launch, query the status, then release a background task.
The task is implemented within a C++ class, which members are protected from concurrent read/write via an std::mutex.
My issue comes when I expose a C interface for this background task. Basically I have say the following functions (assuming task_t is an opaque pointer to an actual struct containing the real task class):
task_t* mylib_task_create();
bool mylib_task_is_running(task_t* task);
void mylib_task_release(task_t* task);
My goal is to make any concurrent usage of these functions thread-safe, however I'm not sure exactly how, i.e. that if a client code thread calls mylib_task_is_running() at the same time that another thread calls mylib_task_release(), then everything's fine.
At first I thought about adding an std::mutex to the implementation of task_t, but that means the delete statement at the end of mylib_task_release() will have to happen while the mutex is not held, which means it doesn't completely solve the problem.
I also thought about using some sort of reference counting but I still end up against the same kind of issue where the actual delete might happen right after a hypothetical retain() function is called.
I feel like there should be a (relatively) simple solution to this but I can't quite put my hand on it. How can I make it so I don't have to force the client code to protect accesses to task_t?
if task_t is being deleted, you should ensure that nobody else has a pointer to it.
if one thread is deleting task_t and the other is trying to acquire it's mutex, it should be apparent that you should not have deleted the task_t.
shared_ptrs are a great help for this.
I have this call stack to perform a heavy computation:
// QML
StyledButton {
onButtonClicked: {
registeredCppClass.undoHandler.createCommand()
}
}
void UndoHandler::createCommand()
{
m_undoStack->push(new Command());
}
class Command : public QUndoCommand
{
public:
Command();
virtual ~Command();
virtual void undo();
virtual void redo();
// ...
private:
// Handler does the logic
LogicHandler *m_logicHandler;
// Output by logic handler
QString m_outputName;
};
void Command::redo()
{
if (/* */) {
} else {
// Run heavy computation
m_outputName = m_logicHandler->run();
}
}
QString LogicHandler::run()
{
// Heavy computation starts
}
Intention
I intend to implement QThread by this approach to prevent GUI from getting non-responsive while heavy computation is being done. But I don't know where QThread and Worker class need to be implemented. Should they be within:
UndoHandler::createCommand
Command::redo
LogicHandler::run
... ?
What is the best location for QThread and Worker considering their signal-slot connections?
The general advice is to never read QThread documentation. Follow that up with never read Linux thread documentation. I say this as someone who has written quite a few books on software development.
The long answer is threading wasn't well thought out early on and there is a lot of, now bad, information out there. During Qt 3.x and I believe early Qt 4.x one was supposed to derive a class from QThread and override the run(). You can imagine just how well that worked for newbie developers unfamiliar with threads in general and unable to design in mutex or other access protection when manipulating things in multiple threads.
Your design makes it appear you have read some of this documentation. It's still floating around out there.
At some point during Qt 4.x we were no longer supposed to derive from QThread. Instead we were supposed to just create a QThread and moveToThread(). Kinda sorta worked but you could still end up with "dangling threads" if your program didn't follow the happy path through the code.
Around the same time, at least as far as my exposure, we also got a global thread pool.
Your design is really flawed because you looked at old doc. Not your fault. The old doc tends to turn up first in searches.
Visit this GitHub repo and pull down the project. The only dev_doc setup documentation I have completed is for Fedora. I will be working on Ubuntu this morning if I don't get interrupted. Be sure to check out the diamond-themes branch.
Yes, this is using CopperSpice, but CopperSpice is a fork of Qt 4.8 and this is the only concrete code example I could think of off the top of my head. You can build and run the editor or you can poke-and-hope by reading advfind_busy.cpp. What you are looking for is how QFuture is used. That source file is only about 200 lines long and it has a short header file.
Throw out your current design. You need QFuture and QtConcurrent::run().
Note: The header files for these things are different in name and location when compared to current Qt 5.x. That much you will need to look up if you choose to stay with Qt. How you use this stuff is not.
Note 2: If you don't have some kind of throttle control to limit each of these tasks to a single thread instance you will need to dynamically create and destroy QFuture objects. This means you have to have some kind of list or vector keeping track of them and your object destructor needs to walk that list killing off the threads and deleting the objects.
If you want to go on a journey setting up CopperSpice on Ubuntu it is spread across a multi-part blog post starting here.
IMHO, your intentions are correct, and you are headed in the right direction (leaving aside the argument for using QtConcurrency -- thread pools and futures -- since that's not pertinent to the immediate question). Let's address the first part: the objects and execution flow.
As the classes have been outlined in the code snippets, you will need to take extra care to correctly push them across thread boundaries. If you think for a moment, the worker object is created in the calling thread, therefore some of the object's members will also be created in the calling thread. For members which are pointers, this does not pose much of a problem, because you may elect to delay the creation of those objects until after the enclosing object instance has been created and moved to the worker thread. But, embedded objects are created when the object is constructed. If the embedded object derives from QObject, it will have its thread affinity set to the caller thread. In such a case, signals won't work properly. To alleviate this problem, it is often easiest to pass the work thread to the worker object's constructor, so the worker object is able to move all of its embedded objects to the worker thread.
Second, assuming the following:
Command holds a unique instance of LogicHandler, and
LogicHandler does not have state, and
LogicHandler is a subclass of QObject, and
LogicHandler is the worker class
My advice would be to place the spinning up of the thread in Command::redo, then connect the signals similar to advice given at the bottom of this article. Also, you would not set Command.m_outputName to the return value of LogicHandler::run. LogicHandler::run should return void. Instead, you should add a signal to LogicHandler that emits the string value when it has finished processing; then, add a slot in Command to handle that. A QString can easily be marshaled across thread boundaries (make sure you make the connections of the proper type, see here).
The connecting of the worker startup method, to the threads started signal gets the execution started. There is no need to inherit from QThread and override run. The worker should also emit a finished signal, that should be connected to the thread's quit slot. The worker's finished signal should also be connected to both the thread's and worker's deleteLater slot. When these are setup, just call the thread's start method.
From there, the execution will return from redo, and you will be notified that the worker is finished when it emits a signal (the one I mentioned that you will need to add) and passes the output string. If the lifetime of the worker is different (I'm guessing longer, since you need to spin up a thread to do long operation) from the instance of Command, then you will need to connected the return value signal from the worker object to a different object.
Working on a cpp project, where I need something like runtime event handler. My primary goal is to keep a track of various events that takes place in a sample program and based on the events specific handlers are triggered.
These event triggering handlers/functions are not contributing anything to the global objective of the sample program, but are just keeping track over various events in the cpp sample program.
My question is it prossible to create soemthing like custom eventhandlers in cpp?
If yes, is there any tutorial for creating such custom eventhandler?
eg:
Event are like failed to enter while loop. successfully entered while loop, created object, deleted object, changed global variable etc.
The simplest form of event handler is a registered callback function pointer:
enum Events {
FailedEnteringWhileLoop ,
SuccessfullyEnteredWhileLoop ,
};
typedef void(EventHandler*)(Events);
void MyEventHandler(Events ev) {
switch(ev) {
case FailedEnteringWhileLoop:
// Do something
break;
case SuccessfullyEnteredWhileLoop:
// Do something
break;
}
}
EventHandler evh = MyEventHandler;
bool whileLoopEntered = false;
while(condition) {
if(!whileLoopEntered) {
whileLoopEntered = true;
(*evh)(SuccessfullyEnteredWhileLoop);
}
}
if(!whileLoopEntered) {
(*evh)(FailedEnteringWhileLoop);
}
I am looking for events like failed to enter while loop. successfully
entered while loop, created object, deleted object, changed global
variable etc.
The C++ language itself does not track these kinds of things as "events". Generally speaking it doesn't provide hooks into any of the various fundamental activities that happen across code.
So to do what you're asking for requires building an infrastructure yourself and working it into your code in various ways. (Or finding someone else who has done the same sort of work already and made it available. Although you still would have to integrate it into your code.)
To give some idea of what might have to be done:
For creating and deleting objects you can override the new and delete operators. But that doesn't cover stack/local/etc objects. Otherwise you could wedge something the constructors and destructors of every class you want to track, or even have all of them derive from a common base class which encapsulates the tracking.
For changes to a variable, you would have to wrap that variable in a container which only exposes the ability to change it through member functions. Then those could be coded to raise events.
For entering loops... You're out of luck because a loop isn't an entity that can be extended or hooked. You literally have to put some kind of call at every loop you want to track.
As for the rest of the infrastructure, you would probably end up doing something like having all of those various "events" call to some kind of global logging object. If you need different things catch different events over the course of a program, then you might also need to build a way of registering and de-registering listeners (the listeners themselves being based on an interface to derive from or std::function or whatever suits your use case).
But in the end since there isn't an out-of-the-box way provided by the language, you might want to re-consider what you really want and what you hope to achieve with it. In fact you might be better off asking your question in terms how to accomplish the end goal you wanted this for rather than how to do this "event" system.
I'm in a situation where I think that two implementations are correct, and I don't know which one to choose.
I've an application simulating card readers. It has a GUI where you choose which serial port, and speed to use, and a play and stop button.
I'm looking for the best implementation for reader construction.
I have a SimulatorCore class who's living as long as my application
SimulatorCore instantiate the Reader class. And it will be possible to simulate multiple readers on multiple serial port.
Two possibilities:
My Reader is a pointer (dynamic instantiation), I instantiate it when play button is hit, delete it when stop button is hit.
My Reader is an object (static instantiation), I instantiate it in SimulatorCore constructor then create and call Reader.init() and Reader.cleanup() into my Reader class and call these when play and stop are being hit
I personally see the functional side, and I clearly want to use pointer, and do not have any reader instantiate if no reader are simulated.
Someone say me that I should use static instantiation (Reason : for safety, and because "it's bad to use pointer when you have choice to not use them")
I'm not familiar with them, but I think I can also use smart pointer.
Code samples: 1st solution:
class SimulatorCore
{
play(){reader = new Reader();};
stop(){delete reader; reader = nullptr;};
private:
Reader *reader;
}
Code samples: 2nd solution:
class SimulatorCore
{
play(){reader.init();};
stop(){reader.cleanup();};
private:
Reader reader;
}
The code is unstest, I've juste wite it for illustration.
What is the best solution? Why?
You can easily use shared_ptr/unique_ptr:
class SimulatorCore
{
play(){_reader = make_shared<Reader>();};
stop(){_reader = nullptr};
private:
shared_ptr<Reader> _reader;
}
That will solve your problem right way, I guess.
Dynamic allocation gives some problems, for example, with throwing exception (there can be memory losing if between play() and stop() there will be thrown exception, for example, and stop() will never be called). Or you can just forget somewhere call stop() before destruction of SimulatorCore, it is possible if program is heavy.
If you never tried smart pointers, it is good chance to start doing it.
You should generally avoid performing dynamic allocation with new yourself, so if you were going to go with the 1st solution, you should use smart pointers instead.
However, the main question here is a question of logic. A real card reader exists in an idle state until it is being used. In the 2nd solution, what do init and cleanup do? Do they simply setup the card reader into an idle state or do they start simulating actually having a card being read? If it's the first case, I suggest that this behaviour should be in the constructor and destructor of Reader, and then creating a Reader object denotes bringing a card reader into existence. If it's the second case, then I'd say the 2nd solution is pretty much correct, just that the functions are badly named.
What seems most logical to me is something more like this:
class SimulatorCore
{
play(){reader.start();};
stop(){reader.stop();};
private:
Reader reader;
}
Yes, all I've done is change the function names for Reader. However, the functions now are not responsible for initialising or cleaning up the reader - that responsibility is in the hands of Reader's constructor and destructor. Instead, start and stop begin and end simulation of the Reader. A single Reader instance can then enter and exit this simulation mode multiple times in its lifetime.
If you later want to extend this idea to multiple Readers, you can just change the member to:
std::vector<Reader> readers;
However, I cannot know for certain that this is what you want because I don't know the logic of your program. Hopefully this will give you some ideas though.
Again, whatever you decide to do, you should avoid using new to allocate your Readers and then also avoid using raw pointers to refer to those Readers. Use smart pointers and their corresponding make_... functions to dynamically allocate those objects.
It clearly depends on how your whole program is organized, but in general, I think I would prefer the static approach, because of responsability considerations:
Suppose you have a separate class that handles serial communication. That class will send and receive messages and dispatch them to the reader class. A message may arrive at any time. The difference of the dynamic and static approaches is:
With the dynamic approach, the serial class must test if the reader actually exists before dispatching a message. Or the reader has to register and unregister itself in the serial class.
With the static approach, the reader class can decide for itself, if it is able to process the message at the moment, or not.
So I think the static approach is a bit easier and straight-forward.
However, if there is a chance that you will have to implement other, different reader classes in the future, the dynamic approach will make this extension easier, because the appropriate class can easily be instanciated at runtime.
So the dynamic approach offers more flexibility.
I have a singleton class for logging purpose in my Qt project. In each class except the singleton one, there is a pointer point to the singleton object and a signal connected to an writing slot in the singleton object. Whichever class wants to write log info just emit that signal. The signals are queued so it's thread-safe.
Please critique this approach from OOP point of view, thanks.
=============================================================================================
Edit 1:
Thank you all your applies, listening to opposite opinions is always a big learning.
Let me explain more about my approach and what I did in my code so far:
Exactly as MikeMB pointer, the singleton class has a static function like get_instance() that returns a reference to that singleton. I stored it in a local pointer in each class's constructor, so it will be destroyed after the constructor returns. It is convenient for checking if I got a null pointer and makes the code more readable. I don't like something as this:
if(mySingletonClass::gerInstance() == NULL) { ... }
connect(gerInstance(), SIGNAL(write(QString)), this, SLOT(write(QString)));
because it is more expensive than this:
QPointer<mySingletonClass> singletonInstance = mySingletonClass::getInstance();
if(singletonInstance.isNull) { ... }
connect(singletonInstance, SIGNAL(write(QString)), this, SLOT(write(QString)));
Calling a function twice is more expensive than creating a local variable from ASM's point of view because of push, pop and return address calculation.
Here is my singleton class:
class CSuperLog : public QObject
{
Q_OBJECT
public:
// This static function creates its instance on the first call
// and returns it's own instance just created
// It only returns its own instance on the later calls
static QPointer<CSuperLog> getInstance(void); //
~CSuperLog();
public slots:
void writingLog(QString aline);
private:
static bool ready;
static bool instanceFlag;
static bool initSuccess;
static QPointer<CSuperLog> ptrInstance;
QTextStream * stream;
QFile * oFile;
QString logFile;
explicit CSuperLog(QObject *parent = 0);
};
I call getInstance() at the beginning of main() so make sure it is read immediately for each other class whenever they need to log important information.
MikeMB:
Your approach is making a middle man sitting in between, it makes the path of the logging info much longer because the signals in Qt are always queued except you make direct connection. The reason why I can't make direct connection here is it make the class non-thread-safe since I use threads in each other classes. Yes, someone will say you can use Mutex, but mutex also creates a queue when more than one thread competing on the same resource. Why don't you use the existing mechanism in Qt instead of making your own?
Thank you all of your posts!
=========================================================
Edit 2:
To Marcel Blanck:
I like your approach as well because you considered resource competition.
Almost in every class, I need signals and slots, so I need QObject, and this is why I choose Qt.
There should be only one instance for one static object, if I didn't get it wrong.
Using semaphores is same as using signals/slots in Qt, both generates message queue.
There always be pros and cons regarding the software design pattern and the application performance. Adding more layers in between makes your code more flexible, but decreases the performance significantly on those lower-configured hardware, making your application depending one most powerful hardware, and that's why most of modern OSes are written in pure C and ASM. How to balance them is really a big challenge.
Could you please explain a little bit more about your static Logger factory approach? Thanks.
I do not like singletons so much because it is always unclean to use them. I have even read job descriptions that say "Knowledge of design patterns while knowing that Singleton isn't one to use". Singleton leads to dependecy hell and if you ever want to change to a completely different logging approach (mabe for testing or production), while not destroying the old one you, need to change a lot.
Another problem with the approch is the usage of signals. Yes get thread savety for free, and do not interrupt the code execution so much but...
Every object you log from needs to be a QObject
If you hunt crashes your last logs will not be printed because the logger had no time to do it before the program crashed.
I would print directly. Maybe you can have a static Logger factory that returns a logger so you can have one logger object in every thread (memory impact will still be very small). Or you have one that is threadsave using semaphores and has a static interface. In both cases the logger should be used via an interface to be more flexible later.
Also make sure that your approach prints directly. Even printf writes to a buffer before being printed and you need to flush it every time or you might never find crashes under bad circumstances, if hunting for them.
Just my 2 cents.
I would consider separating the fact that a logger should be unique, and how the other classes get an instance of the logger class.
Creating and obtaining an instance of the logger could be handled in some sort of factory that internally encapsulates its construction and makes only one instance if need be.
Then, the way that the other classes get an instance of the logger could be handled via Dependency injection or by a static method defined on the aforementioned factory. Using dependency injection, you create the logger first, then inject it into the other classes once created.
A singleton usually has a static function like get_instance() that returns a reference to that singleton, so you don't need to store a pointer to the singleton in every object.
Furthermore it makes no sense, to let each object connect its log signal to the logging slot of the logging object itself, because that makes each and every class in your project dependent on your logging class. Instead, let a class just emit the signal with the log information and establish the connection somewhere central on a higher level (e.g. when setting up your system in the main function). So your other classes don't have to know who is listening (if at all) and you can easily modify or replace your logging class and mechanism.
Btw.: There are already pretty advanced logging libraries out there, so you should find out if you can use one of them or at least, how they are used and adapt that concept to your needs.
==========================
EDIT 1 (response to EDIT 1 of QtFan):
Sorry, apparently I miss understood you because I thought the pointer would be a class member and not only a local variable in the constructor which is of course fine.
Let me also clarify what I meant by making the connection on a higher level:
This was solely aimed at where you make the connection - i.e. where you put the line
connect(gerInstance(), SIGNAL(write(QString)), this, SLOT(write(QString)));
I was suggesting to put this somewhere outside the class e.g. into the main function. So the pseudo code would look something like this:
void main() {
create Thread1
create Thread2
create Thread3
create Logger
connect Thread1 signal to Logger slot
connect Thread2 signal to Logger slot
connect Thread3 signal to Logger slot
run Thread1
run Thread2
run Thread3
}
This has the advantage that your classes don't have to be aware of the kind of logger you are using and whether there is only one or multiple or no one at all. I think the whole idea about signals and slots is that the emitting object doesn't need to know where its signals are processed and the receiving class doesn't have to know where the signals are coming from.
Of course, this is only feasible, if you don't create your objects / threads dynamically during the program's run time. It also doesn't work, if you want to log during the creation of your objects.