I have this class inside a qt application that has some data defined:
class TableView:public QWidget
{
Q_OBJECT
public:TableView (QWidget * parent = 0);
std::vector < float > arr;
and some class functions and so on..
Now I want to add a socket server in another thread (posibly from inside this class) that is able to access data from this class when it recives something from the socket, calculate
new data and return.
For the test I used:
//defines
DWORD WINAPI SocketHandler(void* lp);
DWORD WINAPI starttremeshserver(void* lp);
CreateThread(0,0,&starttremeshserver, (void*)csock , 0,0);
This works. Now I need something easy and platform independent. Maybe something with qthread since I am working in qt.
So the question is, can I make a new thread function inside a class that can access class data. ty
Qt provides everything you need. Your needs are as follows:
Thread-safe (serialized) access to the data members of the TableView class.
Networking primitives.
Flexibility to move network access to a separate thread.
You are probably receiving data from the network, and want to update the arr member. You'd do it like so:
Create a QObject-derived class, say Processor, that has a slot that sets up the network connection (probably a QTcpServer). Upon a connection, use QTcpSocket to exchange data. Make sure all your data handling is done in slots in the class. When you have new values to update in the vector, simply emit some signal, like hasFloat(int,float).
Add a setFloat(int,float) slot in the TableView.
Connect the setFloat signal from the instance of Processor to your TableView.
At this point, everything runs in the GUI thread, but the code is non-blocking since you never wait for network data; you respond to the signals emitted by QTcpServer and QTcpSocket. You can leave it like that if you wish.
Having the Processor class run in a separate thread, if your benchmarking shows that your main thread is CPU bound, is then trivial:
int main(int argc, char** argv) {
bool separateThread = true;
QApplication app(argc, argv);
TableView view;
Processor proc;
connect(&proc, SIGNAL(hasFloat(int,float)), &view, SLOT(setFloat(int,float)));
QThread thread;
if (separateThread) {
thread.start();
proc.moveToThread(&thread);
}
view.show();
const bool rc = app.exec();
if (thread.isRunning()) {
thread.exit(); // tells the event loop in the thread to bail out
thread.wait(); // waits for the above to finish
}
return rc;
}
There's this misconception that spreading things across threads somehow magically makes them better. Threads are a solution to a particular problem: CPU-boundedness of the computations being done, and blocking APIs. If your processing is trivial, you are not likely to be CPU bound. Qt provides nonblocking, asynchronous networking. Thus, usually, spinning a second thread is entirely unnecessary.
You must show real numbers first to show you otherwise. Else you're buying into the cargo cult of threading: oh, it's networking, it must go into a separate thread. Nope, not necessarily. Measure first. Understand what you're doing.
The reason for thread safety in the above code is as follows: when you move the Processor instance to a different thread, Qt will reconnect all signal-slot connections using Qt::QueuedConnection type. Thus, when Processor emits hasFloat, it will internally cause an event to be queued in the event queue of the thread where TableView lives -- the GUI thread, in this case. When the event loop spins (here it'd be the application's event loop) -- it'll pick up the event and execute a call to TableView::setFloat. This ensures that the access to the arr data member is serialized and there are is no possibility of concurrent access from multiple threads.
I'd personally look for more high level socket support, something based on boost perhaps, anyway for threads you can use <thread> in C++11.
To answer your specific question:
class Foo
{
private:
void spinthread()
{
thread t([this] {
this->bar = 12;
});
}
private:
int bar;
}
If you're using Win32 threads API, the thread proc has a parameter which you can use to pass your instance to during the CreateThread call.
Qt has threading support as can be found here.
In addition to threads and accessing the data, you'll need synchronization for thread-safe code. This is called pthread mutex in linux, and in Qt its called QMutex as mentioned here.
You can find the Qt networking primitives here.
Using the Qt implementation of these threading and networking primitives will be portable, so should work for you on windows.
Regarding your question about creating a thread function from a class that accesses data on that class, the answer is yes. Instead of creating a thread function, it would be better to create a thread object, namely a QThread. When you create the thread object, you'll need to pass a reference to the instance of said class, which will allow the thread to access the class instance.
Related
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.
I have a couple questions.
Is it possible to initialize a QApplication object on one thread and destroy it on another?
Why does QApplication have to run on the same thread in which it was allocated?
Is it possible to run QApplication::processEvents() on a different thread from where the QApplication object was created? Will this work if the thread to call processEvents was a non-QT thread?
It may be possible but Qt is not tested for it. I imagine that it's possible to hack that in - you'd need code changes. It won't ever work on MacOS, unless you're having only QCoreApplication in mind - neither the QApp.. nor QGuiApp.. supports other threads on that platform, and possibly on other platforms as well (Windows excepted). I have no idea why would you do that, though. Once the QApplication event loop is running on the given thread, it can terminate on command and automatically destroy the application instance. In fact, it's trivial:
int main(int argc, char *argv[]) {
QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));
QtConcurrent::run([]{
// this runs in a worker thread, and causes the application
// object to destroy itself and then the program to exit
QThread::sleep(2);
QCoreApplication::quit();
});
auto rc = app.exec();
app.reset();
// perhaps do some other processing here that doesn't need
// a qApp instance
return rc;
}
Why not? QApplication doesn't have to "run" at all, so who cares? You can run an event loop on any thread, and the one in the main thread doesn't need to run at all unless you have some objects in the main thread that you want to deliver events to. The event loop in the main thread is special because that's the only one where QWidget instances are supported. That's a Mac OS limitation, so if you want to write portable code, you can only instantiate QApplication on the main thread (i.e. something that has int main() on the call stack).
Yes, with the caveat that it doesn't do what you likely think it might be doing. The meaning of QCoreApplication::processEvents means "drain the event queue of the current thread". In Qt, an event loop is a per-thread resource. You can run an event loop on any thread - in fact, QThread::run does precisely that: its run() does, in essence QEventLoop().exec().
And you can only drain the event loop of whatever thread you're in, because there's no access provided to any other event loop - it wouldn't make sense: "draining" an event queue means dispatching events in the thread of the event loop that runs on that queue, and when you execute in any given thread, you by definition aren't executing code in some other thread and thus can't drain the event queue there. QCoreApplication::processEvents is equivalent to QAbstractEventDispatcher::instance()->processEvents(), where instance() is the event dispatcher instance in the current thread.
Now you might say: But hey, what if we could take the event queue data that belongs to some other thread, and invoke all those QObject::event methods in another thread? This is not only not designed to ever work, you're might simply deadlock on internal Qt mutexes and that'd be the end of it. There's no point to it anyway. On most any platform, you can send the equivalent of an interruptible sleep signal to any thread, and inject a code to execute - i.e. QCoreApplication::processEvents - within that signal. On Windows, you'd use APCs for it, on Unix it'd be some combination of signals and other clever code. It is possible to emulate APCs to an extent by doing stack inspection to determine whether the context is safe, and if so doing things that would not otherwise be allowed.
There's no such thing as a "non-Qt" thread. A thread is a platform resource, by definition. QThread is not a "Qt" thread. It's a handle to the platform's thread resource. Even better: it's a handle that's automatically created when there's a demand for it, so you can always refer to the current thread, even if your code hasn't created such a handle explicitly before.
Perhaps you need to tell us what you're trying to do. There's something very fundamental that's missing in your question.
First of all, I am not using a GUI. (In case that matters.) I want to send the path of a file to a thread (as char*), have it process the file, then return. Preferably, I would like the thread to stop when it's not being used.
The Qt documentation shows two approaches to creating threads:
Create a QObject and moveToThread().
Create a QThread then start() it when it's needed.
In the two approaches above, what is happening if I don't have a run() function? I don't have one because I don't see a way of passing the char* to run(), so I'm using a signal. Do I have to start() the thread in order for it to work properly? If so, what does this do if there is no run()? Can I just create it, connect the signals/slots, then call it when I need it? Does one of the above approaches offer an advantage in this case?
UPDATE: Thank you for the quick response Johannes Schaub and thuga.
If I'm using QObject->moveToThread(), that thread is then running in an event loop? And this event loop sleeps when there is no input? (If so, that's good.) The thread (event loop) is tied to QObject's signals and slots, right? So I need to then have this object's scope be the calling thread by putting it in the constructor? (And quit() wait() in the destructor) It therefore runs for the entire lifetime of the original thread?
I don't think I need to have a slot for the QThread, because I only want to invoke it, not communicate back and forth. (Except the finished signal.) So I would do something like this:
a. Create an instance of the QThread:
WorkerThread *workerThread = new WorkerThread(this);
b. Send it the string. This is the part I'm not sure about. I think Johannes tried to explain, but I'm still not clear. I can't send the filename via a signal/slot because QThreads shouldn't use slots. (but can in moveToThread() case because of queued connections)
c. Start the Thread with .start()
The default run function then calls exec, which enters an event loop. The loop sleeps if it doesnt have an event to process.
The object that you move to the thread is not the QThread object itself. It is another object. The QThread object itself just has the event loop and is still associated with the main thread (its affinity is the main thread).
If the thread operates in the background, you best use QString as the filename and then call a respective "processFile" function or similar of that object that you pass the file name. The invocation can either be by a signal slot connection or an explicit QMetaObject::invokeMethod, using the connection type QueuedConnection (which passes an event into the event loop of the thread of the object, so your file names are automagically queued by being contained in that internal slot call event).
If I'm using QObject->moveToThread(), that thread is then running in an event loop?
Those are completely unrelated. A bare QThread is running the event loop as soon as you start() it. For this to happen you don't need to move any objects to it. Of course the event loop is dormant since there are no incoming events for it to process - so the thread, in spite of having been started, doesn't consume any CPU.
The thread (event loop) is tied to QObject's signals and slots, right?
Signals and slots are simply function call sources and sinks that you can link up. They have not much to do with event loops.
When the sender and receiver objects reside in different threads, the delivery of a slot call is implemented by posting a QMetaCallEvent to the object's event queue. That even, like all events, is given to QObject::event(QEvent*) method. That method acts on the QMetaCallEvent and executes the slot call.
So I need to then have this Object's scope be the calling thread by putting it in the constructor? (And quit() wait() in the destructor) It therefore runs for the entire lifetime of the original thread?
The object's lifetime is decoupled from thread's lifetime. An object that is moved to a given thread can only be destructed from that thread. If the thread terminates first, the object becomes threadless (its thread() returns nullptr), and it can be destructed from any thread, or moved to another thread. A threadless object can't receive any events, but of course it can receive direct slot calls. Queued slot calls won't work since those are delivered as events initially, and only internally converted into calls.
I don't think I need to have a slot for the QThread, because I only want to invoke it, not communicate back and forth.
A QThread is a thread controller. There's very little reason to subclass it. In almost all cases you can either use a QObject that has been moved to the thread, or QtConcurrent::run.
So I would do something like this: [...] Create an instance of the QThread: [...] Send it the string.
You want to send the string to an object that lives in the thread, not to the thread itself.
Here's a small example:
// main.cpp
#include <QThread>
#include <QCoreApplication>
#include <QDebug>
class Worker : public QObject {
public:
Q_SLOT void say(const QString & str) { qDebug() << str; }
};
/// A thread that's safe to destruct at any time.
class Thread : public QThred {
using QThread::run;
public:
~QThread() { quit(); wait(); }
};
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
Worker worker;
Thread thread;
thread.start();
worker.moveToThread(&thread);
// Equivalent to invoking the say slot from a signal
QMetaObject::invokeMethod(&worker, "say", Q_ARG(QString, "hello"));
//
QMetaObject::invokeMethod(&app, "quit");
return app.exec();
}
#include "main.moc"
It sounds like your thread is supposed to process a char* and then wait. If this is the case, there's a third option available to you where you have a single function that runs in a separate thread and then exits, using QtConcurrent::run()
Simple example:
void workerFunction(QString const &data){
// ...
}
void callingFunction(){
// ....
char *data = .....;
QFuture<void> future = QtConcurrent::run(workerFunction, QString(data));
}
EDIT:
If you need more features than a single threaded function but not as many as a fully-fledged subclass of QThread, there is also the QRunnable/QThreadPool pair as a convenient intermediate option.
I am using Qt and wish to write a class that will perform some network-type operations, similar to FTP/HTTP. The class needs to connect to lots of machines, one after the other but I need the applications UI to stay (relatively) responsive during this process, so the user can cancel the operation, exit the application, etc. My first thought was to use a separate thread for network stuff but the built-in Qt FTP/HTTP (and other) classes apparently avoid using threads and instead rely on signals and slots. So, I'd like to do something similar and was hoping I could do something like this:
class Foo : public QObject
{
Q_OBJECT
public:
void start();
signals:
void next();
private slots:
void nextJob();
};
void Foo::start()
{
...
connect(this, SIGNAL(next()), this, SLOT(nextJob()));
emit next();
}
void Foo::nextJob()
{
// Process next 'chunk'
if (workLeftToDo)
{
emit next();
}
}
void Bar::StartOperation()
{
Foo* foo = new Foo;
foo->start();
}
However, this doesn't work and UI freezes until all operations have completed. I was hoping that emitting signals wouldn't actually call the slots immediately but would somehow be queued up by Qt, allowing the main UI to still operate.
So what do I need to do in order to make this work? How does Qt achieve this with the multitude of built-in classes that appear to perform lengthy tasks on a single thread?
If you're doing a length job in the UI thread the UI is going to freeze. One way to avoid this is to call once in a while QCoreApplication::processEvents().
You should be VERY careful however to understand what this does before you decide to do it. Calling this function means that a GUI event can fire in the middle of your operation. If this event can in turn create some more jobs you can end up starting a new job while in the middle of the old job.
I wouldn't be so quick dismissing the worker thread approach. It has the advantage of completely separating the work from the GUI so you are certain that something that began is going to finish.
You should also consider that Windows especially sometimes introduces non trivial delays to GUI loops. If the host is somewhat busy or in a memory thrashing state you'll find that GUI events may take up to several long seconds to finish and return control to your processing.
Use QThread with a run method like this:
void run(){ exec(); }
this will provide another execution loop, where you can do your "hard work" without acutally freezing the UI.
Note: Make sure to actually use the thread's execution loop by adding
moveToThread(this);
at the end of the Constructor of your QThread derived Thread class (the doc doesn't say much about it)
Follow up question to:
This question
As described in the linked question, we have an API that uses an event look that polls select() to handle user defined callbacks.
I have a class using this like such:
class example{
public:
example(){
Timer* theTimer1 = Timer::Event::create(timeInterval,&example::FunctionName);
Timer* theTimer2 = Timer::Event::create(timeInterval,&example::FunctionName);
start();
cout<<pthread_self()<<endl;
}
private:
void start(){
while(true){
if(condition)
FunctionName();
sleep(1);
}
}
void FunctionName(){
cout<<pthread_self()<<endl;
//Do stuff
}
};
The idea behind this is that you want FunctionName to be called both if the condition is true or when the timer is up. Not a complex concept. What I am wondering, is if FunctionName will be called both in the start() function and by the callback at the same time? This could cause some memory corruption for me, as they access a non-thread safe piece of shared memory.
My testing tells me that they do run in different threads (corruption only when I use the events), even though: cout<<pthread_self()<<endl; says they have the same thread id.
Can someone explains to me how these callbacks get forked off? What order do they get exectued? What thread do they run in? I assume they are running in the thread that does the select(), but then when do they get the same thread id?
The real answer would depend on the implementation of Timer, but if you're getting callbacks run from the same thread, it's most likely using signals or posix timers. Either way, select() isn't involved at all.
With signals and posix timers, there is very little you can do safely from the signal handler. Only certain specific signal safe calls, such as read() and write() (NOT fread() and fwrite(), or even new and cout) are allowed to be used. Typically what one will do is write() to a pipe or eventfd, then in another thread, or your main event loop running select(), notice this notification and handle it. This allows you to handle the signal in a safe manner.
Your code as written won't compile, much less run. Example::FunctionName needs to be static, and needs to take an object reference to be used as a callback function.
If the timers run in separate threads, it's possible for this function to be called by three different threads.