First of all, forgive me if there’s an obvious solution, I’m completely new to the use of thread (and only know a bit about the theory).
I’m currently developing an application in which I want to use threads. Basically, it retrieves data an displays it on a graph in real time with Qt.
I’ve followed the guidelines of this post on how to use correctly QThread, but then I’m concerned with a few details.
Basically, I want to implement a pause, that will stop the real-time query and update, which can then be resumed later on.
At the moment, my class looks like this :
class DataProcessor : public QObject{
Q_OBJECT
public:
DataProcessor();
~DataProcessor();
//Internal details
public slots:
//mapped to the started() signal of a QThread
void process();
signals:
void finished();
void error(QString error);
}
I wonder how I could implement a pause feature. After reading Bruce Dawson’s post In praise of Idleness, I’ve noted a few methods that I should avoid (most importantly, avoiding busy wait)
Then, it doesn’t quite fit my needs, as Bruce talks about waiting for another thread to exit its critical section. Here, I just want to pause the work done by the thread’s worker on user input, and restart it the same way.
My question is: how can I implement an efficient pause for my threaded code ?
I’ve thought of using a sort of flag in my worker, that could be set from the main (something like bool m_paused;), but once set, I don’t know how I can actually pause efficiently my worker.
Note: This question was not written by me, but it describes my problem exactly. Source: link
Related
I am trying to use boost::asio async client example with a simple Qt GUI like:
A little snippet from my app:
The button click SLOT:
void RestWidget::restGetCall()
{
networkService ntwkSer("www.boost.org","80");
connect(&ntwkSer, SIGNAL(responseReady(std::string)), this, SLOT(showResponse(std::string)));
ntwkSer.get("/LICENSE_1_0.txt");
}
The networkService class is just a wrapper of the above linked boost sample code.Its derived from QObject class for signal,slot mechanism.
void networkService::get(const std::string & path)
{
// boost::thread (boost::bind(&networkService::networkCall,this,path));//this gives me sigabrt
networkCall(path);//this works fine, and i get output as pictured above.
}
void networkService::networkCall(const std::string path)
{
tcp::resolver::query query(host_, port_);//also these host,port fields come out to be invalid/garbage.
//tcp::resolver::query query("www.boost.org","80");//still doesnt resolve the SIGABRT
resolver_.async_resolve(query,
boost::bind(&networkService::handle_resolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::iterator,
path));
io_service.run();
}
The problem, is when i run the io_service.run() from the boost::thread. i get SIGABRT.
also he host_,port_ networkService wrapper class fields inside the networkService::networkCall(path) function on debugging come out to be invalid, which get saved while constructing:
networkService ntwkSer("www.boost.org","80");
The obvious reason for boost::thread is to make GUI non-blocking,since io_service() has its own eventloop. My intention is to run boost::asio async calls in a seperate boost thread, and notify the GUI thread with QT's Q_OBJECT signal slot mechanism.
I don't get the reason of SIGABRT and also why could the field values of host_ and port_ become invalid once i start using boost::thread.
PS: This same setup, behaves correctly with boost::thread from a similar commandline application (no Qt GUI code), i.e when the networkService class is not hacked for Qt signal/slot to notify the main GUI thread. Here, i use the boost::asio's response from within the boost::thread.
Edit:
as per responses to my question, i tried this... i disabled Q_OBJECT signal/slot and QObject derivation of the networkservice class, to be sure MOC isnt messing things up.. but still, the issue prevails, i get access violation on windows vs sigabrt on linux. The issue of the networkservice object's fields getting corrupted is also present, eventually getting access violation.
In effect no change in behaviour.
before launching thread:
from inside thread
access violation on continue...
So, even without MOC , the issue is still there.
Edit 2:
Im sorry for bothering.. i did a huge mistake, of using a local networkService object from within the boost::thread, which got scoped out when the thread actually ran!
It's difficult to get the asio io_service.run() function to "play well" with the Qt event loop.
It's easier to use a Qt slot that calls io_service::poll() or io_service::poll_one() and then connect that slot to a QTimerEvent.
And it's even easier to use QNetworkAccessManager instead of asio see Qt Client Example
The problem is that with qt only one thread is allowed to manipulate the gui in qt. That is the one calling QApplication::exec. This is done to remove complexity for the users of qt and due to that QApplication / message loop being a singleton. That being said there is some magic going on in qt with threads. All QObjects are assigned a thread. By default the one on which they are created. When a signal slot connection is made it is determined how to actually dispatch the call. If the objects belong to the same thread a signal is dispatched by directly / synchronous invoking the slot. If the objects are assigned to distinguished threads a message is send from one thread to another to invoke the slot on the thread that is assigned to the object where the slot lives. This is what you actually need here.
The problem with your code is that both of your QObjects are created on the same thread. They are therefore assigned the same thread. So the slot which manipulates the GUI is called directly from your worker thread and remember this is prohibited! Since your worker is not the one calling QApplication::exec. To override the automatics and convince to correctly do the thread switch when calling the slot you must use Qt::QueuedConnection when doing the connect.
connect(&ntwkSer, SIGNAL(responseReady(std::string)), this, SLOT(showResponse(std::string)), Qt::QueuedConnection);
For example, I have multi-threaded application which can be presented as:
Data bigData;
void thread1()
{
workOn(bigData);
}
void thread2()
{
workOn(bigData);
}
void thread3()
{
workOn(bigData);
}
There are few threads that are working on data. I could leave it as it is, but the problem is that sometimes (very seldom) data are modified by thread4.
void thread4()
{
sometimesModifyData(bigData);
}
Critical sections could be added there, but it would make no sense to multi-threading, because only one thread could work on data at the same time.
What is the best method to make it sense multi-threading while making it thread safe?
I am thinking about kind of state (sempahore?), that would prevent reading and writing at the same time but would allow parallel reading.
This is called a readers–writer lock. You could implement what is called a mutex to make sure no one reads when write is going on and no one writes when reads are going on. One way to solve the problem would be to have flags. If the writer is got something to modify, then switch on a lock. Upon which NO MORE readers will get to read and after all the current readers have finished, the writer will get to do its job and then again the readers read.
So I have a single-threaded game engine class, which has separate functions for input, update and rendering, and I've just started learning to use the wonderful boost library (asio and thread components). And I was thinking of separating my update and render functions into separate threads (and perhaps separate the input and update functions from each other as well). Of course these functions will sometimes access the same locations in memory, so I decided to use boost/thread's strand functionality to prevent them from executing at the same time.
Right now my main game loop looks like this:
void SDLEngine::Start()
{
int update_time=0;
quit=false;
while(!quit)
{
update_time=SDL_GetTicks();
DoInput();//get user input and alter data based on it
DoUpdate();//update game data once per loop
if(!minimized)
DoRender();//render graphics to screen
update_time=SDL_GetTicks()-update_time;
SDL_Delay(max(0,target_time-update_time));//insert delay to run at desired FPS
}
}
If I used separate threads it would look something like this:
void SDLEngine::Start()
{
boost::asio::io_service io;
boost::asio::strand strand_;
boost::asio::deadline_timer input(io,boost::posix_time::milliseconds(16));
boost::asio::deadline_timer update(io,boost::posix_time::milliseconds(16));
boost::asio::deadline_timer render(io,boost::posix_time::milliseconds(16));
//
input.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoInput,this)));
update.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoUpdate,this)));
render.async_wait(strand_.wrap(boost::bind(&SDLEngine::DoRender,this)));
//
io.run();
}
So as you can see, before the loop went: Input->Update->Render->Delay->Repeat
Each one was run one after the other. If I used multithreading I would have to use strands so that updates and rendering wouldn't be run at the same time. So, is it still worth it to use multithreading here? They would still basically be running one at a time in separate cores. I basically have no experience in multithreaded applications so any help is appreciated.
Oh, and another thing: I'm using OpenGL for rendering. Would multithreading like this affect the way OpenGL renders in any way?
You are using same strand for all handlers, so there is no multithreading at all. Also, your deadline_timer is in scope of Start() and you do not pass it anywhere. In this case you will not able to restart it from the handler (note its not "interval" timer, its just a "one-call timer").
I see no point in this "revamp" since you are not getting any benefit from asio and/or threads at all in this example.
These methods (input, update, render) are too big and they do many things, you cannot call them without blocking. Its hard to say precisely because i dont know whats the game and how it works, but I'd prefer to do following steps:
Try to revamp network i/o so its become fully async
Try to use all CPU cores
About what you have tried: i think its possible if you search your code for actions that really can run in parallel right now. For example: if you calculate for each NPC something that is not depending on other characters you can io_service.post() each to make use all threads that running io_service.run() at the moment. So your program stay singlethreaded, but you can use, say, 7 other threads on some "big" operations
I'm new to multithread programming. I wrote this simple multi thread program with Qt. But when I run this program it freezes my GUI and when I click inside my widow, it responds that your program is not responding .
Here is my widget class. My thread starts to count an integer number and emits it when this number is dividable by 1000. In my widget simply I catch this number with signal-slot mechanism and show it in a label and a progress bar.
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
MyThread *th = new MyThread;
connect( th, SIGNAL(num(int)), this, SLOT(setNum(int)));
th->start();
}
void Widget::setNum(int n)
{
ui->label->setNum( n);
ui->progressBar->setValue(n%101);
}
and here is my thread run() function :
void MyThread::run()
{
for( int i = 0; i < 10000000; i++){
if( i % 1000 == 0)
emit num(i);
}
}
thanks!
The problem is with your thread code producing an event storm. The loop counts very fast -- so fast, that the fact that you emit a signal every 1000 iterations is pretty much immaterial. On modern CPUs, doing a 1000 integer divisions takes on the order of 10 microseconds IIRC. If the loop was the only limiting factor, you'd be emitting signals at a peak rate of about 100,000 per second. This is not the case because the performance is limited by other factors, which we shall discuss below.
Let's understand what happens when you emit signals in a different thread from where the receiver QObject lives. The signals are packaged in a QMetaCallEvent and posted to the event queue of the receiving thread. An event loop running in the receiving thread -- here, the GUI thread -- acts on those events using an instance of QAbstractEventDispatcher. Each QMetaCallEvent results in a call to the connected slot.
The access to the event queue of the receiving GUI thread is serialized by a QMutex. On Qt 4.8 and newer, the QMutex implementation got a nice speedup, so the fact that each signal emission results in locking of the queue mutex is not likely to be a problem. Alas, the events need to be allocated on the heap in the worker thread, and then deallocated in the GUI thread. Many heap allocators perform quite poorly when this happens in quick succession if the threads happen to execute on different cores.
The biggest problem comes in the GUI thread. There seems to be a bunch of hidden O(n^2) complexity algorithms! The event loop has to process 10,000 events. Those events will be most likely delivered very quickly and end up in a contiguous block in the event queue. The event loop will have to deal with all of them before it can process further events. A lot of expensive operations happen when you invoke your slot. Not only is the QMetaCallEvent deallocated from the heap, but the label schedules an update() (repaint), and this internally posts a compressible event to the event queue. Compressible event posting has to, in worst case, iterate over entire event queue. That's one potential O(n^2) complexity action. Another such action, probably more important in practice, is the progressbar's setValue internally calling QApplication::processEvents(). This can, recursively call your slot to deliver the subsequent signal from the event queue. You're doing way more work than you think you are, and this locks up the GUI thread.
Instrument your slot and see if it's called recursively. A quick-and-dirty way of doing it is
void Widget::setNum(int n)
{
static int level = 0, maxLevel = 0;
level ++;
maxLevel = qMax(level, maxLevel);
ui->label->setNum( n);
ui->progressBar->setValue(n%101);
if (level > 1 && level == maxLevel-1) {
qDebug("setNum recursed up to level %d", maxLevel);
}
level --;
}
What is freezing your GUI thread is not QThread's execution, but the huge amount of work you make the GUI thread do. Even if your code looks innocuous.
Side Note on processEvents and Run-to-Completion Code
I think it was a very bad idea to have QProgressBar::setValue invoke processEvents(). It only encourages the broken way people code things (continuously running code instead of short run-to-completion code). Since the processEvents() call can recurse into the caller, setValue becomes a persona-non-grata, and possibly quite dangerous.
If one wants to code in continuous style yet keep the run-to-completion semantics, there are ways of dealing with that in C++. One is just by leveraging the preprocessor, for example code see my other answer.
Another way is to use expression templates to get the C++ compiler to generate the code you want. You may want to leverage a template library here -- Boost spirit has a decent starting point of an implementation that can be reused even though you're not writing a parser.
The Windows Workflow Foundation also tackles the problem of how to write sequential style code yet have it run as short run-to-completion fragments. They resort to specifying the flow of control in XML. There's apparently no direct way of reusing standard C# syntax. They only provide it as a data structure, a-la JSON. It'd be simple enough to implement both XML and code-based WF in Qt, if one wanted to. All that in spite of .NET and C# providing ample support for programmatic generation of code...
The way you implemented your thread, it does not have its own event loop (because it does not call exec()). I'm not sure if your code within run() is actually executed within your thread or within the GUI thread.
Usually you should not subclass QThread. You probably did so because you read the Qt Documentation which unfortunately still recommends subclassing QThread - even though the developers long ago wrote a blog entry stating that you should not subclass QThread. Unfortunately, they still haven't updated the documentation appropriately.
I recommend reading "You're doing it wrong" on Qt Blog and then use the answer by "Kari" as an example of how to set up a basic multi-threaded system.
But when I run this program it freezes my GUI and when I click inside my window,
it responds that your program is not responding.
Yes because IMO you're doing too much work in thread that it exhausts CPU. Generally program is not responding message pops up when process show no progress in handling application event queue requests. In your case this happens.
So in this case you should find a way to divide the work. Just for the sake of example say, thread runs in chunks of 100 and repeat the thread till it completes 10000000.
Also you should have look at QCoreApplication::processEvents() when you're performing a lengthy operation.
I’m writing a test that expects to receive an event from an object that it is calling. Specifically, I am calling out to an object that connects to an AIX machine via SSH (using the open source Granados project), then disconnecting, and I want to make sure I receive the OnConnectionClosed event that is being raised during the disconnect. It sounds simple enough, and I’ve written many tests like this in the past, but this time some strange behavior is occurring that I believe is related to threading.
Basically, the object I call is raising the ‘OnConnectionClosed’ event on a different thread than what I call it from. What I’m seeing is that when I run the test by selecting ‘Debug Test’ from the UI, it passes, but if I choose ‘Run Test’, it fails (even if there are no breakpoints set during the debug run). I’ve done some Googling and found this post that seems to indicate that by default the MSTest host runs in Single Thread mode but that a config change can make it run in Multi Thread mode. This sounded like it would logically fix my problem, but of course, it did not.
Some other posts I’ve come across also make me think that MSTest is simply not monitoring the background threads (so the events raised by them are not being ‘heard’). This would also make sense, and since it seems to work in debug mode, and it seems like the fix above should logically solve that problem, then I’m confused as to why it’s not working. It is possible that I’m simply not correctly dealing with the threads, although I would expect that to still be a problem in debug mode if it were the case.
Has anyone else tried to test something in a similar way? If so, did you encounter similar problems? And if so, how did you resolve them?
I’ve pasted the relevant unit test code below (I’ve removed the connection info for security reasons).
[TestClass]
public class SSHReaderTests
{
private bool received = false;
private delegate bool SimpleFunc();
[TestInitialize]
public void MyTestInitialize()
{
received = false;
}
[TestMethod]
public void Should_raise_OnReaderConnectionClosed_event_after_successful_connection_is_disconnected()
{
IReader reader = new SSHReader();
reader.OnReaderConnectionClosed += delegate
{
received = true;
};
reader.Connect("*****", "*****", "*****");
//Assert.IsTrue(reader.IsConnected);
reader.Disconnect();
//Assert.IsFalse(reader.IsConnected);
Assert.IsTrue(WaitUntilTrue(delegate {
return received; }, 30000, 1000));
}
private static bool WaitUntilTrue(SimpleFunc func, int timeoutInMillis, int timeBetweenChecksInMillis)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while(stopwatch.ElapsedMilliseconds < timeoutInMillis)
{
if (func())
return true;
Thread.Sleep(timeBetweenChecksInMillis);
}
return false;
}
}
Use the WaitHandle classes in the System.Threading namespace. Either, AutoResetEvent or ManualResetEvent. The difference between the two is that AutoResetEvent lets one thread proceed each time it is set, while ManualResetEvent releases all waiting threads on set.
The reason your example doesn't work has to do with compiler optimizations. The code does not actually get compiled to what you would think at first glance. Most likely, the compiler will do something like place the local variable in a register and never actually fetch it during your loop that checks. You can avoid this type of thing with the volatile keyword, but I would highly recommend reading up on threading and concurrency for more details. Joe Duffy's blog at http://www.bluebytesoftware.com is a great resource to get started, and I highly recommend his Concurrency Programming on Windows book that is coming out soon.
Not exactly what you arr asking about, but you may find some workable solutions or at least ideas by checking out the MS Research project called CHESS. It's for multithreaded concurrency testing in .net.