Performance issues while waiting for other programs

Posted on 2008-10-06
Last Modified: 2013-11-17

I am using Borland C++ builder to create an application that will do the following:

Launch another program in execution (with CreateProcess()) and suspend the program flow until the launched program has finished executing. However, I don't want all flow to stop executing, just everything besides the GUI. If I use WaitForSingleObject(), the GUI also freezes until the program has finished. I want to be able to press a "stop" button that will instantly terminate the launched process. For this, I have the following, admittedly hackish solution:

Use _beginthread() to launch the function that does the program execution, have a variable done that is initially zero, then have a loop in the function that used _beginthread() : while (!done) Application->ProcessMessages; done will be set to 1 once the thread finishes.

This fixes the problem, at least for fast computers. On slower computers (not really slow, 2.0ghz P4 slow) not only does this also freeze the interface, it also makes the launched program run incredibly slow, making the whole thing freeze for a long time.

So, I'm open to any suggestions. How can I execute the program, suspend a certain function's execution until it finishes, keep the GUI responsive and now slow everything down?
Question by:Dastas
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22666627
LVL 39

Expert Comment

ID: 22668111
>>>> while (!done)
If you would put a

   Sleep(100);  // wait 100 msec to give other processes a chance

in the while block, the screen wouldn't freeze.

Author Comment

ID: 22668901

That seem even less elegant to me. Also, doesn't Sleep make the whole program wait? So it WOULD freeze for 100 msec even on fast comps. Not really a solution...

jaime_olivares: will take a look and implement today and post back.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 39

Expert Comment

ID: 22671169
>>>> Also, doesn't Sleep make the whole program wait?
No, only the thread where it was called.

The method is called polling and is - though not being elegant - a often used, simple and clean solution. However in your case it might be not necessary. If I understand your code correctly, you were processing messages while waiting for the launched process to terminate. If so, why not simply return after starting the thread and let the normal message loop do the processing? You could evaluate the 'done' flag in all handlers which should not be invoked while the launched process was active.

BTW, the (normal) message loop itself is polling as well, and it has a little sleep included (in idle time processing) which prevents from consuming all CPU time (as your loop did which didn't pause).

Author Comment

ID: 22677920

I have implemented that, and it's not working as I need it to. It doesn't lag or anything, but I also have some timers in place that time the program's execution and auto-terminate it in case it exceeds a time limit. The method presented in that question bugs those timers (I assume because of the way MsgWaitForMultipleObjects() works...). Is there any way around this? Perhaps if I create a thread, MsgWaitForMultipleObjects() on the thread handle and start the process from the thread and use normal WaitForMultipleObjects() there? Would this allow my executed program and my termination conditions to run correctly?


You are correct about Sleep, I'm sorry. Also correct about the method, if I do this:

            while ( !done )

The lag is reduced, however I don't like that I can still see when the GUI freezes for a short while. Also, I'm not sure how this would behave on slower computers...

Isn't there a better way?

". If I understand your code correctly, you were processing messages while waiting for the launched process to terminate. If so, why not simply return after starting the thread and let the normal message loop do the processing?"

I'm not sure how I would go about doing this. My process-launching thread is started in a for-loop, and after the thread start, I have the while ( !done ) loop. If I don't have this while loop, the for loop will keep launching threads, and I don't want that. Perhaps it's easier to understand what I mean if I tell you exactly what I'm working on. It's a specialised benchmarking program that executes other programs that work on some files, and then it compares results, then launches the same program on another data set and so on for a number of times. Each execution is timed and results are reported after each execution for that execution.
LVL 39

Expert Comment

ID: 22682554
>>>> I'm not sure how I would go about doing this.
I assumed a normal Windows program which is message driven. Then, it has a message loop in the main thread like that

   while (PeekMessage(msg))

In the DispatchMessage message handlers were called, e. g. after a button was clicked by the user.

None of the handlers may call sleep or message handling was paused, the screen freezes. If you need to do lengthy jobs, you have two choices: either break the jobs down to smaller parts and fastly return to the message loop after handling that part *or* put the the execution of the lengthy handling into a thread. The thread must not consume all CPU but should make sleeps in order to give other threads some CPU time. Instead of sleeps it also could wait for events what would slow down the thread as well and - if made clever - is a most elegant way - though not always makeable.  Note, the main thread in this scenario is a reactive thread. As far as I understand your app, you actively has to call Application->ProcessMessages() what is much more difficult to get into balance. If using threads you need synchronization when displaying results. You normally do that by calling PostMessage which is a thread-safe way to communicate between worker thread(s) and main thread. You also can have separate queue containers for each thread to send/receive jobs, messages, results. Then, you have to synchronize access to the queue(s) by using a mutex or critical section which makes the access exclusively, thus thread-safe.

Author Comment

ID: 22694309
I used this and it seems to work perfectly even on slow computers (no lag or freeze on 1.4 ghz processors). My questions is, is this safe to do, or can it somehow fail in certain situations?

The meaning of the done variable remains the same, and the threading scheme I explained in my first post:

            while ( !done )
                  if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
LVL 39

Accepted Solution

itsmeandnobodyelse earned 500 total points
ID: 22694937
>>>> is this safe to do,
Yes it is safe. Any Windows program has a message loop similiar or identical. Heowever, you shouldn't forget the TranslateMessage as it calls PreTranslateMessage which gives a chance to suppress or transform messages for some important purposes, e. g. the TAB and ENTER key often were pretranslated by applications.

Author Comment

ID: 22701393
Ok, thank you. I have awarded the points.

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
printf performancy 11 106
youtube blocking politics 4 105
collection output issue 9 96
Survey branching tutorial 11 78
This is about my first experience with programming Arduino.
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question