Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Help with terminating a process

Oliviu
Beginner
1,480 Views

Hi,

I am trying to create a routine that launches an application from within my
code. However, in certain conditions (unfortunately not all of them avoidable),
the external application goes non-responsive and I'm having problems in
terminating it.

I appologise for any over-simplified or incorrect terminology, but I'm not
a programmer, I'm an engineer, more comfortable with equations and numbers than
codes, and I'm learning Fortran on the go, only as the necessity appears :)

I'll explain a bit what I'm trying to do.

The external application (XFOIL.exe) is launched in batch mode. I've set the
path to the batch file in a CHARACTER variable:

CHAR = 'C:\WingOptim\xfoilrun.bat'

Next, I create the new process for the XFOIL executable:

STARTUPINFO = T_STARTUPINFO(SIZEOF(STARTUPINFO), &
              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)


RET = CREATEPROCESS (CHAR, &
   '"'//CHAR//'" -CHILD'C, &
   NULL_SECURITY_ATTRIBUTES, &
   NULL_SECURITY_ATTRIBUTES, &
   FALSE, &
   0, &
   NULL, &
   NULL_CHARACTER, &
   STARTUPINFO, &
   PROCESSINFO)

Finally, after a time that should be more than enough for normal execution,
I close the process and the associated handles.

RET = WAITFORSINGLEOBJECT (PROCESSINFO%HPROCESS, &
      20000)
RET = CLOSEHANDLE (PROCESSINFO%HTHREAD)
RET = CLOSEHANDLE (PROCESSINFO%HPROCESS)
RET = TERMINATEPROCESS (PROCESSINFO%HPROCESS, &
      JM_EXIT_CODE)

However, there are certain situations when the XFOIL application goes non-
responsive, as I've already mentioned.

The problem that I have is that when this happens, even though control is
transfered back to my main code and its execution continues, a certain
"residual" image of the XFOIL.EXE process remains open in my Windows task list.

If the non-responsive scenario happens several times, each time a new residual
process is created, and slowly my CPU load increases to the point where the
execution of my code becomes impossible (each XFOIL.exe residual eating 25%
of CPU maximum load).

I've also tried to forcefully close XFOIL.exe by passing the taskkill command
to the system. While my XFOIL process is open, i get its ID:

PID = PROCESSINFO%DWPROCESSID

Then, I pass the command to the system:

WRITE (STRING,110) PID
110 FORMAT ('TASKKILL /F /PID ', I5)
RESULT = SYSTEM(STRING)

However, this has no extra effect, and residuals keep building up.

The only way I found to close the residual processes is to manually force them
to close from the task list of the Windows Task Manager. However, this is not
feasible because the execution time of my code is long (a couple of days).

Can anyone point me in the right direction?

Thanks,

Oliviu

0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,480 Views

Did you check the return status from TerminateProcess? (If it fails, RET will be 0 and you then need to call GetLastError.) My guess is that you should call TerminateProcess before closing the handles.

0 Kudos
Oliviu
Beginner
1,480 Views

Hi,

I've switched the order of TerminateProcess and CloseHandle, so now I terminate after closing the handles. It din't solve the problem.

I've also checked the return value of TerminateProcess. It is 0 each time XFOIL.EXE succesfully executes and closed (but this makes sense, since there is nothing left to terminate), however it is not 0 when XFOIL.EXE blocks. From the poit of view of my main code, the XFOIL process was succesfully terminated after the imposed waiting period, and thus my code goes on. The "residual image" of XFOIL in the Windows task list is still there however.

Oliviu

0 Kudos
Steven_L_Intel1
Employee
1,480 Views

It is likely your program is stuck in the rundown process. MSDN says "The terminated process cannot exit until all pending I/O has been completed or canceled. When a process terminates, its kernel object is not destroyed until all processes that have open handles to the process have released those handles."

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,480 Views

If your controlling application and XFOIL are sharing files might the XFOIL be sitting at (a hidden) "I/O error, retry?". Essentially waiting for user input? This would inhibit the termination, at least for some system time-out interval (like when you do a reboot with an app sitting at a confirmation prompt).

Note, your XFOIL may also intercept the terminate process, for purposes of clean-up and/or query as to if termination is to be permitted. IOW it could say "do not terminate" with or without a application supplied prompt.

Also, if you are using a pipe between your main process and XFOIL, if you forgot to close the pipe this might muck up things.

Jim Dempsey

0 Kudos
Oliviu
Beginner
1,480 Views

Hi,

Yes, the information exchange between my main app and XFOIL in done through file sharing. My main app creates the settings file for XFOIL.EXE, then XFOIL.EXE runs in batch mode with the provided setting file and outputs the results in a results file. After the termination of XFOIL.EXE process, my main app searches for the results file. If it finds it, it reads the results, checks the results for errors and moves on. If it does not find it, it assigns user-defined values to the variables it was supposed to read (but could not find) and moves on.

I do not think XFOIL is waiting for any user input, because I can easily "force" it to go non-responsive by opening the XFOIL.EXE independently, providing a set of more delicate input values, and so I can replicate exactly the same behaviour as when it runs in batch, from my main process. However, when this independant run "blocking" occurs, the taskkill command easily closes the troublesome process, somethign that does not succesfully occur from within my code

As a non-specialist and beginner programmer, I am not using a pipe between the two processes (at leat not intentionally anyway :)  ), just simple communication through input and output files.

I am thinking at what Steve Lionel has said, about the kernel image of the process not being destroyed until my main process has released all the handles to the XFOIL process. I have tried to forcefully close my main EXE after the "residual XFOIL process" scenario has happened, and the moment my main app has closed, all the XFOIL "residual" images have also closed. So I'm guessing this could be the problem.

Are there any other ways of ensuring the proper closure of all the handles my main app has over the XFOIL process, exept what I have already provided?

RET = WAITFORSINGLEOBJECT (PROCESSINFO%HPROCESS, &
      20000)
RET = CLOSEHANDLE (PROCESSINFO%HTHREAD)
RET = CLOSEHANDLE (PROCESSINFO%HPROCESS)

Maybe if I create the XFOIL process with some other settings?

Thank you for any advice,

Oliviu

0 Kudos
IanH
Honored Contributor III
1,480 Views

This is probably unrelated, but your CreateProcess call doesn't look right for a batch file.  Is that the real code?  If so - the application (first argument) probably should be cmd.exe, and that first argument certainly needs to be null terminated.

Again unrelated, but rather than unconditionally calling TerminateProcess consider checking the return code from WaitForSingleObject - if the process object signalled (which is a consequence of process termination) there's no point terminating it again.

As Steve says, your process definitely wants to close its access to the handle for the process (the handle for the thread can be closed earlier) after the TerminateProcess call.

0 Kudos
Reply