VC++ 2005 Threading for Complete Morons

C

cory.laflin

Hi. I have what I believe to be a very simple task I'm trying to
accomplish in VC++ 2005 and I simply can't make it work. I have a good
working knowledge of C, a basic-to-middling knowledge of C++, and a
novice-level knowledge of OOP in general and Visual Studio in
particular.

I am not a full-time programmer. I am an aerospace engineer who is
trying to make a useful tool. Remember this.

Anyway, the task breaks down to this. I've made a GUI for one of my
simulator codes. It reads in data from fields and runs the simulator
from that; that all works fine. Here's the problem: I have a Kill
button on the main UI that I need use of while my sim code is running.
The obvious answer would be to put the sim execution in another thread,
leaving the first thread to handle the UI. Problem: There is a
ProgressBar on the UI that needs to update as the simulator moves
through its allotted time. I need this so that the user will know when
the sim is hanging so that s/he can hit the Kill button.

Secondary problem: I also have a message bar that I'd like to update
with a "Simulation finished" message when the case has completed
successfully. This means I need some way for the first thread to know
when the second thread has returned.

I have Googled this subject to death, in these groups, in MSDN, and on
the rest of the Web. I have an 1,100-page book specifically dealing
with VC++ 2005 that says NOTHING, about thread programming. The online
articles I have encountered have either been so simple as to be
worthless in this application, or so complicated as to lose me two
paragraphs in.

This CANNOT, simply CANNOT be a hard thing to do, even for an amateur
programmer, this should be only a step or two beyond a message box with
a "Hello World" and a button. I know there are at least four different
ways to launch threads in a VC++ program: native C++, MFC calls, CLI
Thread classes, and CLI ThreadPool classes. I've tried the last two,
and I'm currently using the last one because it enabled me to actually
pass an argument to it, albeit through a structure that I had to make
specifically for it.

Can somebody please help me?
 
N

Nathan Mates

Anyway, the task breaks down to this. I've made a GUI for one of my
simulator codes. It reads in data from fields and runs the simulator
from that; that all works fine. Here's the problem: I have a Kill
button on the main UI that I need use of while my sim code is running.
The obvious answer would be to put the sim execution in another thread,
leaving the first thread to handle the UI. Problem: There is a
ProgressBar on the UI that needs to update as the simulator moves
through its allotted time. I need this so that the user will know when
the sim is hanging so that s/he can hit the Kill button.

Frankly, I think that writing a threaded application without really
understanding threads is going to lead to a LOT of bugs, problems, and
the like. Threads can make your app a lot more nondeterministic, and
while they might be able to make the first 90% of your work easier,
they make the last 10% take the other 90% of your time. It's simpler
and easier to code w/o threads initially.

If you want to crunch data and respond to user input at the same
time, why not start with the assumption that it might just be possible
to do that w/o threads? A lot of videogames do just that. Write your
main loop like this:

bool quitNow = false;
while(!quitNow)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
quitNow = true;
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

// Crunch a bit of data. In a videogame, we'd do something
// like (1) Get inputs, (2) Update everything (3) draw scene

Think();
}

Just write Think() so that it takes at most a half second per call,
and you'll do fine. When your app isn't busy crunching data, then have
Think() call Sleep(0) to be nice to other apps. Until you really
understand threads, I'd advise not using them.

Nathan Mates
 
A

AE_Cory

Thanks. Of course the simplest solution is the best. I just needed
somebody who knows what they're doing to tell me that.

I haven't even worked with message handlers before, but I know I have
documentation on those.

Thanks again, and good luck with Mercenaries 2.

-Cory
 
D

David Wilkinson

Hi. I have what I believe to be a very simple task I'm trying to
accomplish in VC++ 2005 and I simply can't make it work. I have a good
working knowledge of C, a basic-to-middling knowledge of C++, and a
novice-level knowledge of OOP in general and Visual Studio in
particular.

I am not a full-time programmer. I am an aerospace engineer who is
trying to make a useful tool. Remember this.

Anyway, the task breaks down to this. I've made a GUI for one of my
simulator codes. It reads in data from fields and runs the simulator
from that; that all works fine. Here's the problem: I have a Kill
button on the main UI that I need use of while my sim code is running.
The obvious answer would be to put the sim execution in another thread,
leaving the first thread to handle the UI. Problem: There is a
ProgressBar on the UI that needs to update as the simulator moves
through its allotted time. I need this so that the user will know when
the sim is hanging so that s/he can hit the Kill button.

Secondary problem: I also have a message bar that I'd like to update
with a "Simulation finished" message when the case has completed
successfully. This means I need some way for the first thread to know
when the second thread has returned.

I have Googled this subject to death, in these groups, in MSDN, and on
the rest of the Web. I have an 1,100-page book specifically dealing
with VC++ 2005 that says NOTHING, about thread programming. The online
articles I have encountered have either been so simple as to be
worthless in this application, or so complicated as to lose me two
paragraphs in.

This CANNOT, simply CANNOT be a hard thing to do, even for an amateur
programmer, this should be only a step or two beyond a message box with
a "Hello World" and a button. I know there are at least four different
ways to launch threads in a VC++ program: native C++, MFC calls, CLI
Thread classes, and CLI ThreadPool classes. I've tried the last two,
and I'm currently using the last one because it enabled me to actually
pass an argument to it, albeit through a structure that I had to make
specifically for it.

Cory:

The way I do this (not universally approved, but it works for me) is put
the work in a worker thread, and report progress back to the main GUI
thread using SendMessage(). The handler updates the progress bar and
returns 0 to stop and 1 to continue (this way you can implement a Cancel
button in the main thread).

When the thread ends I use PostMessage() back to the main thread
immediately before the worker thread function returns. The handler can
then use WaitForSingleObject() on the thread handle (which should return
almost immediately). Now the main thread knows that the worker thread
has finished. If you want, you can call GetExitCodeThread() on the
thread handle to get thereturn code of the therad function.

David Wilkinson
 
R

Roman

Hi. I have what I believe to be a very simple task I'm trying to
accomplish in VC++ 2005 and I simply can't make it work. I have a good
working knowledge of C, a basic-to-middling knowledge of C++, and a
novice-level knowledge of OOP in general and Visual Studio in
particular.

I am not a full-time programmer. I am an aerospace engineer who is
trying to make a useful tool. Remember this.

Anyway, the task breaks down to this. I've made a GUI for one of my
simulator codes. It reads in data from fields and runs the simulator
from that; that all works fine. Here's the problem: I have a Kill
button on the main UI that I need use of while my sim code is running.
The obvious answer would be to put the sim execution in another thread,
leaving the first thread to handle the UI. Problem: There is a
ProgressBar on the UI that needs to update as the simulator moves
through its allotted time. I need this so that the user will know when
the sim is hanging so that s/he can hit the Kill button.


The thread has to check for this:

while(NotDone && !Abort)
{
// compute something
}

The main thread will be able to kill all other threads by:

Abort = TRUE;
Secondary problem: I also have a message bar that I'd like to update
with a "Simulation finished" message when the case has completed
successfully. This means I need some way for the first thread to know
when the second thread has returned.

Non-UI thread cannot update UI. Generally main thread is also UI thread,
which most of the time pumps messages. When this thread does some longer
task, UI stops working.

You can :

.. send particular message from finished thread, so the message will call
a handler in a context of main thread

.. periodically check completion status from main thread by variable

.. periodically call WaitForSingleObject() with zero timeout to see if
thread has finished
I have Googled this subject to death, in these groups, in MSDN, and on
the rest of the Web. I have an 1,100-page book specifically dealing
with VC++ 2005 that says NOTHING, about thread programming. The online
articles I have encountered have either been so simple as to be
worthless in this application, or so complicated as to lose me two
paragraphs in.

This CANNOT, simply CANNOT be a hard thing to do, even for an amateur
programmer, this should be only a step or two beyond a message box with
a "Hello World" and a button. I know there are at least four different
ways to launch threads in a VC++ program: native C++, MFC calls, CLI
Thread classes, and CLI ThreadPool classes. I've tried the last two,
and I'm currently using the last one because it enabled me to actually
pass an argument to it, albeit through a structure that I had to make
specifically for it.

Can somebody please help me?

What I said above is for native Windows API.

You need thread synchronization and those are buzzwords you should Google.

Check on following objects

Event
Mutex
Semaphore
CriticalSection (my favourite)

Usefulness of the objects above overlaps and sometimes you can use one
or another. Event/Mutex/Semaphore work across process (by unique name),
but critical section works only within single process.

Critical Section uses hidden unnamed semaphore and optimizes access by
calling the semaphore API only when necessary, so it is generally way
faster than semaphore itself.

Good luck

Roman
 
A

AE_Cory

Thanks, guys. I think I'll probably go with Nathan's solution for the
problem at hand, but I'm going to do a little self-study using the
other two responses, so that when I need to do this again I've got a
bigger toolbox available.

I really wasn't understanding how the Windows API was working because I
was taking the easy route with CLI stuff. You all pushed me back to
looking at that, and as a result I'm getting a much better feel for it.

-Cory
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top