Adi
Adi

Reputation: 1316

Multithreaded application concept

I have a small architecture doubt about organizing code in separate functional units (most probably threads?). Application being developed is supposed to be doing the following tasks:

  1. Display some images on a screen (i.e. slideshow)
  2. Read the data from external device through the USB port
  3. Match received data against the corresponding image (stimulus)
  4. Do some data analysis
  5. Plot the results of data analysis

My thoughts were to organize the application into the following modules:

  1. GUI thread (+ image slideshow)
  2. USB thread buffering the received data
  3. Thread for analyzing/plotting data (main GUI thread should not be blocked while plotting the data which might consume some more time)

So, what do you generally think about this concept? Is there anything else you think that might be a better fit in this particular scenario?

Upvotes: 2

Views: 553

Answers (6)

John Knoeller
John Knoeller

Reputation: 34218

Because of the way the Windows API works, especially with regard to user input and window ownership. You can really only do UI on a single thread. If you try and use multiple threads, they just end up locking each other out and only 1 thread runs at a time. There are some specialized exceptions, but you have to be a real master of the API to pull it off.

So.

  1. GUI thread, owns the Window, and handles all user input.
  2. USB listening thread, you would know better than I whether this makes sense
  3. Thread(s) for analyzing/plotting data, once again, I can't speak to this, but I'm skeptical that they will really both be running at the same time. It seems more likely this it would be analyze then plot so 1 thread.
  4. Thread for rendering frames for a slideshow.

I'm not sure how plotting isn't the same thing as the slideshow, but I do think you can have a background thread for drawing the slideshow as long as it doesn't display the images. You can render (i.e. draw to a bitmap or DirectX surface) in a background thread, you just can't show it in a window. But you could hand completed bitmaps off to the GUI thread and have it do the actual displaying of the bitmap. This is essentially how a lot of video playback code works.

Upvotes: 3

Jerry Coffin
Jerry Coffin

Reputation: 490728

I can't help thinking that you may be going a bit overboard here. A USB port can't really deliver data terribly quickly -- it's theoretical bandwidth is only 480 Mbits/second, and realistically, it's a pretty rare USB device that can really get very close to that.

Unless the analysis you've mentioned is quite a bit more complex than you've implied, my guess is that a single thread is probably entirely adequate. I'd think hard about using overlapped I/O to read the data, and MsgWaitForMultipleObjects for the main message loop.

It seems to me that the main place you stand a good chance of gaining a lot is in plotting the data after it's processed. It might be worth considering something like OpenGL or DirectX Graphics to do the drawing. Especially if you're producing quite a bit of output, this can give a really substantial speed improvement. In an ideal situation, multiple threads might multiply your speed by the number of available cores -- typically 2 or 4 on today's machines. Drawing the output is likely to be the slowest part of the job, and hardware acceleration can easily speed that up by a considerably larger factor -- 10x is at the low end of what you can typically expect, and 100x is fairly common.

Upvotes: 1

JustJeff
JustJeff

Reputation: 12980

You can probably get away with combining 1 & 2, since the slide-show feature is essentially gui oriented anyway.

For #3, you may be able to make do with some kind of asynchronous I/O methodology, so that you don't need to dedicate a polling thread. Not sure if you can do this with USB, but you can certainly get async I/O with serial and network interfaces, so it's worth looking into.

It's probably a good idea to move heavy-weight tasks like 4 & 5 to their own thread. If you aren't doing the analysis and plotting concurrently, maybe one thread for them both. However, you should really consider how much cpu time these activities will need. If the worst-case analyze-and-plot takes much less than half a second, you might even just perform these actions with a call from the gui. Conversely, if there are cases where this will take longer than that, a separate thread is favorable b/c your users won't like a laggy gui.

Just bear in mind that the dark side of threads lies in the inevitable challenge of coordinating them.

Upvotes: 3

Gregor Brandt
Gregor Brandt

Reputation: 7799

If you are using Builder 2009, you should look at TThread. It has some stuff to simplify thread coding.

Upvotes: 1

David L Morris
David L Morris

Reputation: 1513

A lot of this depends on how much is involved in performing 3 (Do some data analysis.) and 4 (Plot analyzed data.)

My instincts would be:

Definitely have a separate thread for reading the data off the USB. Assuming for a moment that 3 is dependent on reading the data, then I would do 3 in the same thread as reading the data. This will simplify your signaling to the GUI when the data is ready. This also assumes the processing is quick, and won't block the USB port (How is that being read? IO completion ports?). If the processing takes time then you need a separate thread.

Likewise if image slide processing show takes a long time, this should be done in a separate thread. If this can be quickly recalculated depending say in a paint function, I would keep it as part of the main GUI.

There is some overhead with context switch of threads, and for each thread added complexity of signaling. So I would only add a thread to solve blocking of the GUI and the USB port. It may be possible to do all of this in just two threads.

Upvotes: 2

Xorlev
Xorlev

Reputation: 8653

4 and 5 are definitely good ideas. That being said, avoid using low-level threads unless you absolutely must.

I'd check out Boost and Boost::Thread. Not only does it make your code more portable, but I haven't worked with an easier library for threading.

Upvotes: 1

Related Questions