NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

terminate execution while background thread is running

Solved!
Go to solution

After switching from TestStand 4.1 to 2012 I see an interesting problem.

 

I start a MainSequence through the SinglePass execution entry point using the parallel model. In ProcessSetup (in execution N) I start a background thread that does some visualization tasks. Then the model goes through "Initialize TestSockets" and starts my MainSequence (in execution N+1).

 

While the MainSequence is running, execution N hangs in ParallelModel.seq>Single Pass, Step "Wait for TestSockets", as it should be. Usually, when the MainSequence ends, the execution terminates and the execution N advances to the next step "Check for Terminate and Abort" and some time later it runs through ProcessCleanup -- where I would send my background thread a notification to terminate itself.

 

That works as long as I do not start that background thread. But when this thread is running, execution N+1 never leaves the MainSequence. I reach a break point at the end of MainSequence, advance one step, and then all executions are happily displaying a green light and keep on running. So execution N never leaves "Wait for TestSockets" and never reaches ProcessCleanup, so my thread does not get the termination signal etc.

 

But I remember distinctly that this worked in TestStand 4.1 and anyway, I do not understand this. Why does a background thread, started in execution N, prevent execution N+1 from terminating?

 

Regards

 

Peter

 

0 Kudos
Message 1 of 6
(6,077 Views)

In your Sequence Call Advanced Settings for the sequence call that is spawning the thread, what is Automatically Wait for the Thread to Complete at the End of the Current Sequence set to?

 

Maybe?

jigg
CTA, CLA
testeract.com
~Will work for kudos and/or BBQ~
0 Kudos
Message 2 of 6
(6,070 Views)

I rephrase my question:

 

When an execution starts a sequence in a new thread (not waiting for the thread to complete at the end of the sequence), does it have to take care at the end of its MainSequence that the thread is ordered to end itself in order for the execution to terminate?

 

The reason to ask the question thus is that after two days of puzzling I just now stumbled over the solution and do not quite understand what is happening. Therefore, some more background detail:

 

The situation is as follows:

  1. The SinglePass Execution Entry Point creates execution N
    1. ProcessSetup calls a sequence "HMI_Loop1" in a new thread which periodically exchanges system information with a control system user interface
    2. ProcessSetup calls a sequence "Worker" in a new execution N+1; this sequence actually does all the work for the socket
  2. The SinglePass Execution Entry Point starts MainSequence in execution N+2
    1. MainSequence calls a sequence "HMI_Loop2" in a new thread which periodically exchanges socket information with the control system user interface
  3. MainSequence waits for external commands from the control system and passed the commands to the Worker execution mentioned above
  4. At some time, MainSequence receives a Shutdown command from the control system and
    1. passes the Shutdown command to the Worker execution, which ends its loop and signals its termination to MainSequence
    2. MainSequence ends

At that point, execution N+1 (Worker) has ended, execution N (SinglePass) and N+1 (Socket) run on, never terminating. Both HMI_Loop-Threads are still running and - which may be crucial - they are using the same server DLL (not quite OPC, but similar).

 

If I introduce a signal that MainSequence sets when it is about to end and which HMI_Loop2 listens to to end its loop, then everything works. HMI_Loop2 ends, MainSequence ends, thereby ending execution N+2 and finally HMI_Loop1 receives its stop signal from ProcessCleanup and all is well.

 

What I do not understand is: HMI_Loop2 is started with ThreadTerminationOption_Normal, so I assumed, when MainSequence reaches its end, it would terminate its execution and thereby the HMI_Loop2-Thread. This never happened.

 

It was always possible, though, to stop everything by "Debug > TerminateAll", so I assume that MainSequence reaching its end did not terminate the Socket execution by itself, because it "knew" that there was still a thread running under its control. And therefore my question on top.

 

Regards

 

Peter

0 Kudos
Message 3 of 6
(6,069 Views)

It is set to "not wait" because this is started in an underlying sequence call which would otherwise block the rest of the execution.

 

Thanks

 

Peter

0 Kudos
Message 4 of 6
(6,067 Views)
Solution
Accepted by topic author pwaszkewitz

"When an execution starts a sequence in a new thread (not waiting for the thread to complete at the end of the sequence), does it have to take care at the end of its MainSequence that the thread is ordered to end itself in order for the execution to terminate?"

 

What do you mean by terminate? The process models do not normally terminate any executions. Do you mean, "Do all threads in an execution have to complete before an execution completes?"? If so then the answer is yes.

 

I don't completely follow your explanation above. I'm not sure what you mean by signalling, but I think you are misunderstanding what terminate means in TestStand. Termination only happens when either a user explicitly requests an execution to terminate (e.g. terminate all), or your sequence has a post action to terminate or programmatically initiates a terminate. Without termination explicitly happening, executions normally complete when all of their threads are finished executing. If you are spawning new threads and executions, you need to come up with a mechanism for them to know when they should exit. I do NOT recommend relying on or using termination for that. Termination is like aborting (but with cleanup), it's not intended to be something that happens as part of the normal flow of execution. There are many ways to tell your worker threads when to complete. Perhaps this signaling your are referring to is one way. You could also use a teststand notification step, or a boolean by reference parameter.

 

Hope this helps clarify things,

-Doug

0 Kudos
Message 5 of 6
(6,045 Views)

I was probably not quite clear in my explanation. You understood my question correctly, and so the answer is, as I assumed, "yes".

 

I did indeed use the "terminate" incorrectly, referring to a termination by the user or an API call as well as to the natural completion of an execution when all its sequences / threads end. And by signalling I meant exactly that, using a notification or a flag monitored by the thread to tell it, when it should end its operation.

 

So thank you, that clarified things and helped me find a correct solution.

 

Peter

 

0 Kudos
Message 6 of 6
(5,985 Views)