views:

178

answers:

2

I am new to multithreading and have designed a program that receives data from two microcontroller measuring various temperatures (Ambient and Water) and draws the data to the screen. Right now the program is singly threaded and its performance SUCKS A BIG ONE.

I get basic design approaches with multithreading but not well enough to create a thread to do a task but what I don't get is how to get threads to perform seperate task and place the data into a shared data pool. I figured that I need to make a queue that has one consumer and multiple producers (would like to use std::queue). I have seen some code on the gtkmm threading docs that show a single Con/Pro queue and they would lock the queue object produce data and signal the sleeping thread that it is finished then the producer would sleep. For what I need would I need to sleep a thread, would there be data conflicts if i didn't sleep any of the threads, and would sleeping a thread cause a data signifcant data delay (I need realtime data to be drawn 30 frames a sec)

How would I go about coding such a queue using the gtkmm/glibmm library.

+2  A: 

If you're looking for a lock free implementation of this, you won't find one. When data structures are being written to, something needs to keep two threads from simultaneously updating the data structure and corrupting it.

Is there any reason you can't have each thread collect on it's own, with it's own structure, and then combine the results at the end?

Billy ONeal
Each thread would be communicating with the a single uC and would process the data and package it to be drawn to the screen. Would a locking system be easier to implement, not really sure how to implement what you described
Talguy
@Talguy: What is a uC? If you mean microsecond, and you're trying to update the display every microsecond, then no amount of multithreading is going to help you. Displays don't update that fast; you'd be better off using polling in that scenario instead.
Billy ONeal
uC = microcontroller. Sorry for the confusion
Talguy
@Talguy: No problem (abbreviations are perfectly acceptable in comments because they have length limits) If that's the case I would still recommend a polling solution. I.e. the display updates itself once every so often (say, once every 50-100ms should be enough for most purposes). Then there need not be a common set of data between the worker threads, and the UI only needs read access to those threads.
Billy ONeal
I got what your saying. I'm going to go with a dedicated circular buffer like Thomas Matthews suggested
Talguy
+2  A: 

Here's a suggestion:
1. Have two threads, that are responsible for obtaining data and placing into a buffer. Each thread has it's own (circular) buffer.
2. There will be a third thread that is responsible for getting data from the buffers and displaying on the screen.
3. The screen thread sends messages to the data threads requesting some data, then displays the data. The messages help synchronize execution and avoid dead-locks.
4. None of the threads should "wait on single or multiple objects", but poll for events.

Think of this scenario using people. One person is delivering water temperature readings. Another person delivering ambient temperature readings. A third person receives or asks for the data and displays the data (on a white board). The objective is to keep everybody operating at maximum efficiency without any collisions.

Thomas Matthews
To have the GUI thread read from each circular buffer I would have the worker thread supply the gui thread with a pointer to the position of he oldest data object in the buffer and the worker thread would just automatically updated the oldest item in the buffer?
Talguy
No, "don't cross the streams." The worker threads will provide methods for accessing the data. This isolates the data structure from the GUI thread and also prevents headaches with data sharing between tasks. The worker knows the structure of his inventory. Let him give you what you ask for; don't mess with his filing system. ;-)
Thomas Matthews
This is the defiantly the best way to accomplish what I want I am just a little confused on how to implement that link between the gui and worker. The way I am seeing it is that I have an instance of my hardware object in the main thread. HWobj worker thread is launched. HWobj has a method called pop_front() that returns and removes the front item of the circlular queue. When ever the main method calls pop it would get the oldest item left. If this is the right way there would still be a little bit of locking when reading data from the buffer?
Talguy