I can't seem to find an exact answer to the threading question I have. I currently have a program that polls the Kinect V2 sensor for new frame data using OpenNI2. The problem is I need to poll each type of sensor; depth, IR, and RGB separately in order to get them at the same time. Here is where my threading questions comes in, I want to poll each of the three sensors in their own individual thread and when all functions calls have returned continue with the data processing.
I understand how to link each new thread to the main thread to ensure all threads finish before the program exits, but how do I wait in the middle of my program for a specific set of threads to finish? Is there a function or feature of std::thread in c++11 that I am overlooking or is this something that needs to be manually done using a mutex or semaphores?
pseudocode:
std::thread thread_RGB(Kinect::readFrame(Enum::RGB), kinect_1);
std::thread thread_IR(Kinect::readFrame(Enum::IR), kinect_1);
std::thread thread_depth(Kinect::readFrame(Enum::depth), kinect_1);
// Wait for all threads to finish getting new frame data
...
// Process data here
process_data(kinect_1.RGB_data);
process_data(kinect_1.IR_data);
process_data(kinect_1.depth_data);
You need to call .join method to wait for the threads to finish and then destruct them. When you call t.join() there is a check if the thread is still doing something and if the work is done the thread is joined. If the thread is not joinable(there is also t.joinable()) the main thread will wait till the secondary thread finish its work and then join it.
In your case you can add these lines.
thread_RGB.join();
thread_IR.join();
thread_depth.join();
Here is an image I found on google that shows how thread::join() works.
Related
What's the best practice to achieve this :
1 - Thread for gathering data
2 - Wait for (1) to finish and render data
And those, indefinitely
while (true) {
thread tGatherData(getData); // Get data
tGatherData.join(); // Wait for data
thread tRender(render); // Render data
Sleep(3);
}
Using it like this doesn't sound like a good practice because it creates a new thread everytime right ?
How should I proceed ? Thanks
If you don't want to create thread on each iteration of your loop, you may want to start 2 threads: one for gathering information, second for printing it, and place your loop in both threads(you should remember about synchronization)
For example here I've created two threads: first for reading from console, second for printing. Synchronization is done by atomic. The program will stop execution, when it reads 0.
But, as good as I understand your code, you don't need second thread at all. All You need is to place your render function inside main thread. And your gathering function isn't asynchronous. It just create another thread and instantly start to wait for it's finishing, so your program should be single thread
I'm working on writing my own status bar that comprises many modules (workspaces, clock, open windows, etc) that each run in their own thread. Each of these modules independently waits for an event that they detect (e.g. a minute passing for the clock module) and after which they update their internal value which is meant to be read by the main thread that renders the bar itself. My issue now is how do I let the main thread know that an update has happened and it should wake up and print the new bar? I looked into condition variables but since there are no mutexes to synchronize the main and worker threads together it doesn't seem applicable. If I were doing this in rust I'd use an mpsc channel, have my main thread wait to read from it and have the modules send an empty () message when they're updated to trigger the main thread to reprint the bar. Is there an equivalent like this in c++?
It turns out that many threads can easily reference the same condition variable that one thread is waiting on and they can all call notify on it to get the job done.
I have inherited a complex program in my current job and am seeking to reduce image flickering from a stream of data coming over a QTcpSocket.
The program receives the continuous stream of data, processes it, then paints it on the screen with a paintEvent.
The processing function is run based on a signal/slot connection where the signal is readyread() from a QTcpSocket, and the slot is the data processing function. The stream is continuous so this signal/slot is continually firing and updating the painted image on the screen based on the incoming data.
The image flickers constantly, and I assume that the processing in the main event loop could be interfering with the data stream, so my idea was to put the data processing function in its own thread. This data processing function is so thoroughly integrated into the other features of the program, that subclassing the data stream at this point so that I could apply a QThread is not a solution and would be a complete restructure of the entire program, taking tons of time.
So my idea was to use QtConcurrent like so:
void MainWindow::getDataThread(){ //implemented as a slot
wpFuture = QtConcurrent::run(this, &MainWindow::getData);
}
where getData() is the data processing function connected to the readyread() signal:
connect(tcpSocket2, SIGNAL(readyRead()), this, SLOT(getData()));
So I replaced SLOT(getData()) with SLOT(getDataThread()) to allow the data processing function to be run on a new thread that is obtained from the global thread pool. Since the stream is continuous, I believe it is constantly assigning a new thread every time the getData processing function is ran. It does seem to reduce flickering but after about 30 to 60 seconds the program randomly crashes with no specific callouts.
So my question is: Is there a better method for threading my data processing function, without subclassing the data stream? Is my thinking/understanding wrong in my implementation of QtConcurrent in this specific situation?
Thank you.
From your comment I assume your understanding of thread pool is wrong.
There are a number of threads in a thread pool. Each time you call QtConcurrent::run a free thread from the global thread pool is taken and being handed a task to do (MainWindow::getData). If you call QtConcurrent::run several times than every time MainWindow::getData will be executed in (presumably) different thread. If there are no currently available threads in thread pool, you tasks will be queued and handed to threads as they become available later. This way you can have several simultaneous tasks running limited by the number of threads in the thread pool.
Now the problem is, that MainWindow::getData is probably not thread safe by its design. QtConcurrent::run(this, &MainWindow::getData); called several times may result in data race.
If you want a separate single thread to process data then just use QThread (no need to "subclass" anything):
// A thread and its context are created only once
QThread thread;
QObject context;
context.moveToThread(&thread);
// ...
QObject::connect(tcpSocket2, &QTcpSocket::readyRead, &context, [this] () {
this->getData();
}, Qt::QueuedConnection);
thread.start()
Now as long as context object is alive and thread is running each time QTcpSocket::readyRead is emmited - the lambda will be executed.
Still pay attention so that your worker thread and you main thread do not collide in getData.
I want to be able to start a new thread from the main thread in my program. At the moment I'm using the following code:
std::thread acceptThread(Accept);
acceptThread.join();
But that blocks the continuation of the main thread until the acceptThread is "done". I don't want this. I just want it to run on a different thread so the main thread can continue. How do I do this?
What I want is a loop that accepts incoming connections and a loop that sends/receives data. These should be running at the same time.
The entire point of join() is to block until the other thread exits. Just get rid of it. Why'd you add it in the first place?
std::thread acceptThread(Accept);
creates and start a new thread that will call the "Accept" method, which is enough in your case.
Your second line is not needed, join would block the current thread unil the joined one exits.
see http://en.cppreference.com/w/cpp/thread/thread/join
At the moment I am using a producer consumer model for the rendering portion of a realtime graphics application. The consumer will continually look for data in our queue(infinite loop); however I am fearful that this may cause my simulation to get out of sync of the main loop. I think this is the fast producer slow consumer problem - compounded by the fact that the simulation is restrained to a certain amount of time.
Question - what is the best method to keep this all in balance and make sure the consumer has enough time to finish, but also that the simulation does not move to the next frame before we are finished rendering our current frame(or at least be able to detect this and skip rendering the next frame - or interrupt the current frame being rendered) I am currently just interrupting and joining after each consumer is finished
Second Question: if you look at the code below you will see that I am currently just calling interrupt and join after adding rendering jobs to the queue - this allows the thread all the time it needs to complete its operation, and to respond to the interrupt when finished. How can I then reuse threads in a thread pool after interrupt_all and join_all are called? (i.e. if i call drawNextFrame again)
The producer is part of the main thread of execution (I don't think this affects anything)
pseudo code:
void renderSystem::init()
create queue to hold work;
create consumer threads of type RenderConsumer set to watch our queue;
add threads to thread_pool of consumers called 'RenderThreads'
void renderSystem::drawNextFrame()
for each thread in 'RenderThreads' divy up work;
add work assignment to queue;
//RenderThreads will now successfully start pulling data from our queue
renderThreads.interupt_all();
renderThreads.join_all();
int main()
renderer = renderSystem class;
renderer.init()
while(not_gameover)
renderer.drawNextFrame();
doOtherCoolStuff();
profit(?)
return(0)
if you need to look at the consumer class see below:
pseudo code:
RenderConsumer::operator () ()
while(true)
try to dequeue from queue
//digest any packet we get
for each ( pixel in packet )
computePrettyStuff()
//we are now done with packet that we got
this_thread::interruption_point();
I tried to make this simple and quick to digest, thank you for your time
#1. I would do this by counting the amount in the queue after each render. If it too high, then either
a. Dump the queue
b. Set a boolean variable to false
That variable will be shared between the threads, and when the producer sees that it is false, it begins waiting on a condition variable. The consumer then notifies the producer when the queue is down to an acceptable level again.
#2. Probably not possible with join_all, as the postcondition to join_all is
Every thread in the group has
terminated.
according to the reference.
It might however be possible, using barriers instead of join_all, but then you would have to find a way to provide them data, which would invariably end up needing some more shared variables.