LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Drawback of using ProcessSystemEvents?

Hello, I got some problem with temporisation. I saw on this forum a method using the ProcessSystemEvents function instead of using the Delay function.

i.e.

void Tempo(Duree)
{
double time1;
double time2;

    time1 = Timer();
    time2 = Timer();
    while ((time2 - time1) < Duree)
    {
        time2 = Timer();
        ProcessSystemEvents();
    }
}

In my program, i use two timers for acquisitions, one for RS, the other for analog I/O with a lot of Tempo(). When I quit the interface with QuitUserInterface(), it take a long time to shut down. And when I look step by step my program running I saw my timers running several times after the QuitUserInterface().

The stack trace looks like that:

Quit
Tempo
Timer1
Tempo
Timer2
main

My questions are:
    - Should a QuitUserInterface() empty the process event queue and prevent new timer events to happen?
    - Is it really efficient to use ProcessSystemEvent in a delay function since it stack other functions over and over?

I found a solution for timers, I stopped them before quitting the interface but I thought that QuitUserInterface() should do that. 
Who's got programming tips to make something clear and powerful?

Thanks
Yop!
DanY
    
0 Kudos
Message 1 of 8
(4,654 Views)
Hi!

"   - Is it really efficient to use ProcessSystemEvent in a delay function since it stack other functions over and over?"
 
 ProcessSystemEvents is meant to be used to avoid System lockings, that is if you enter a while loop that's consuming a lot of CPU-time, you should manually call ProcessSystemEvents() to "see if something is happening" (e.g. the user clicked a button....).  System timer is not locked (I hope to be rigth...) by user processes.

  Anyway, can you explain better your task? Are you putting delay functions to create time spacing between samples? And also, what is the time to wait you need? Because if you need to wait 1 or more milliseconds, you can use Windows function Sleep() (or similar....), go to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/sleep.asp.

  If you're using a NI board, maybe you should set timing attributes instead of delaying samples manually.

  If you want, let me know!!

graziano




0 Kudos
Message 2 of 8
(4,646 Views)
Thanks for answering

"System timer is not locked (I hope to be rigth...) by user processes"
My timer seems to be suspended where it has done its Tempo and i doubt that the Tempo duration will be respected if a lot of system event have to be processed.

Concerning my application, I need a lot of delay functions in my RS procedures, not in my I/O procedure.
In the stack trace I've shown, I exagerate my delays in my timers to try to understand the behaviour of the ProcessSystemEvents. In some cases it may stuck my app if
the timer1 (in my example) needs timer2 to run, to ends a while loop.

To conclude, what i wanted to do is to validate my Tempo
function to use it instead of the Delay() function. But the ProcessSystemEvent scares me concerning this stack trace. I wanted to use it in an other app to reduce the CPU load but I don't want to introduce some bugs.

Yop!
DanY
0 Kudos
Message 3 of 8
(4,636 Views)
Hi,
   what do you mean by "RS procedures" (I'm not shure about RS meaning.... what do you refer to?).

  What is the timing delay you need between these procedures? I say again that Sleep is a good function in many cases, it does not overload CPU (I think the convenience of using sleep depends upon the number of milliseconds to sleep...).

Bye!

graziano
0 Kudos
Message 4 of 8
(4,634 Views)
I mean RS like rs-232c. I use tempo to wait between readings and writing. Delays vary from 0.01 to 0.5 seconds.
0 Kudos
Message 5 of 8
(4,628 Views)

The code you show above will work just fine. I do something similar all the time when I have long delays in my code and need to check for events occuring during those delays.

However, I think you misunderstand what is going on here.

The function Timer() does not create any sort of timer control, all it does is read the elapsed time from the system timer which is running all the time in the background where you don't have to worry about it. You cannot stop or suspend this timer nor can you reset it to zero (only restarting the machine does that).

The ProcessSystemEvents() function does one thing and one thing only. It signals the user interface manager that you are yielding control so it can check for CVI messages in the message queue. If there are messages in the queue, CVI will dispatch them to the proper callbacks and then return to your delay function. There is only one thing that may be a problem here that I can see, that is if a callback function takes a long time to process, it may delay completion of your Tempo() function. If that is not an issue and you can tolerate longer delays, than you should use this approach. If you can't tolerate the longer delays, you may want to look into using a multi-threaded application to keep the user interface and instrument I/O processing separate.

Now having said all of that, if the delays you need are less than about half a second, I would simply recommend using the Delay() function. The sort of function you have set up is only really useful when the delays are longer (seconds to minutes) and you do not want the program to block user input until Delay() returns.
Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
Message 6 of 8
(4,612 Views)
One way to avoid the problem you are describing is to have a global to check if your application is still running.  Based on that global, time consuming operations can return and you can shut down quickly while still freeing resources.
 
You can make a macro like this:
 
#define process(x,y)  {double tin; tin = Timer(); while(Timer() - tin < (x) ) {ProcessSystemEvents(); if( (y) ) return(-1); }}
and a global:
int no_longer_running = 0;
 
then you can use it like this:
 
process(duree,no_longer_running);
 
and in your quit function add:
no_longer_running = 1;
QuitUserInterface();
 
This implementation is "sloppy" in its timing.  That is the ProcessSystemEvents() might take longer than you think so that the duree might be overshot by some number of milliseconds.
Delay() is the best for short, accurate times; it keeps the processor loaded checking the time without allowing other inputs from that thread.
SDK sleep() is good if you do not need to process system events and dont want your program to appear to be a hog, but might be a little less accurate since in essence you are waiting for a time slice from the OS.
 
If you have a function which uses a lot of process(x,y) or ProcessSystemEvents()  in a single threaded application usually you will want to ensure that only one instance of it can be launched by the user. 
For the RS232 application it is often easier to use callbacks with install com call backs.  That way your application can spend most of its time idling at RunUserInterface() except when it is doing something.  If you can make up a state machine based on the data you receive you will be better off than sending some text, processing system events for awhile, and then trying to read something.  Instead send some text and note what is expected return.  When some text arrives the callback will be called, use the note for what text is expected to guide the processing of the incoming data.
 
 
 
 
 
 
 
 
Message 7 of 8
(4,606 Views)
Thanks for all your answers, I'll try to uses it in my program.

Concerning the temporization, to sum up we could say:

Use "sleep()" to make a thread wait some time.
Use a temporization function with a "ProcessSystemEvents" for long wait that could hang up the interface.
Use "delay()" to wait really short amount of time but with accuracy (In my opinion 0.5s with the delay() function is a little bit too much)

Yop!
DanY


0 Kudos
Message 8 of 8
(4,558 Views)