After starting a process with QProcess::startDetached, how can I stop it later?
Say the main program runs, then starts the detached process, which runs independently. The user closes the main program, then later opens it up again and wants to stop the process. How would I find the process and then stop it?
Is there a way I could prevent the application from the same process twice?
No, it will be decoupled from your application. You could get the the PID of it and then send a SIGSTOP on Linux, but this is platform specific and will not work without POSIX support, like with msvc. You would need to hand-craft your version therein.
Is there a way I could prevent the application from the same process twice?
Yes, by using lock file in the detached process. If that detached process happens to be written in at least partially Qt, you could use the QLockFile class.
If you happen to detach some platform specific process, then you have the same recurring issue again, for sure.
Here's the answer I figured out:
I first start the detached process that generates a unique id. That process write to a file whenever it runs (was a 1 minute timer). When it runs, it writes its id to a file. Then, if there happens to be another one that ran, if it sees a previous one ran, it just writes its id to the file and doesn't run, then, when the next one runs, it sees if its id is already in the file and if it is, it shuts itself off and clears the file, then the next run ends up running freely, being the only one running. This may end up skipping some time.
You can add a timestamp, too, as that might indicate it wasn't run recently and help with deciding whether or not to shut it down. The issue was if I just write the id to a file, when I turn the phone off, the file will say it's still running. The same applies to if it crashes.
Related
I have a multithreaded app that opens a few files (read-only) and does a bunch of calculations based on data in those files. Each thread then generates some output files.
The code runs fine so long as I generate the threads and then delete them then the app exits. If, however, I try to put the thread creation/deletion into a subroutine and call it several times then the threads have problems when they try to re-open the input files. I have an if(inFile==NULL) check within each thread and sometimes that gets triggered but sometimes it just crashes. Regardless, each thread has an fclose() for each file and the threads are properly terminated so the files should always be closed before the threads are recreated.
I can create multiple threads that can open the same input files and that works fine. But if I close those threads and re-create new ones (e.g. by repeatedly calling a subroutine to create the threads) then I get errors when the threads try to re-open the input files.
The crashes are not predictable. Sometimes I can loop through the thread creation/deletion process several times, sometimes it crashes on the second time, sometimes the fourth, etc.
The only thing I can think of is that the OS (Windows 7) takes too long to close the file sometimes, so the next thread is spawned before the file is closed and then there's some kind of error due to the fact that the OS is trying to close the file while the thread is trying to open it. It seems to me that that could trigger the if(inFile==NULL) condition.
But, sometimes when the if(inFile==NULL) condition is not triggered I still get jibberish read in from the input file. So it thinks it has a good file pointer but it clearly does not.
I realize this is probably a tough question to answer but I'm stumped. So maybe someone has an idea.
Thanks in advance,
rgames
I have an .exe Program, which triggers some other files during execution.
So at a given point, the tree might become like:
Main program
-Program 1
-Program 2
-Program 3
Of all these programs I have their PID, so I am able to close them successfully. However, when a user 'brute forces the program' (read close the program manually), I am unable to close these child programs. Is there an option to trigger the closing of child-programs before the main-program itself will actually exit. (Something is for example also possible in an html-page to remind the user e.g. or they really want to leave te page).
Because, when this situation occurs, on the next run the main-program will try to start up these child-programs again, however they are already running. (And the settings of the main-program are time dependent and have to be transferred to the other child-programs on start-up to work properly)
Ideally, I would like to have a cross-platform solution, since I have to make the app available for Windows, Linux and MacOS.
Thanks for your answers.
This is an OS feature and each OS offers it in its own way. Keeping track of the PIDs does not work, for once for the reason you mention (your parent process may itself crash) and second because the child process may spawn grand-children processes of its own that needs to be tracked, and then grand-grand-children and so on.
On Windows this is handled by NT Job Objects by asking for the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE:
Causes all processes associated with the job to terminate when the last handle to the job is closed.
The way to use it is to create the job object in the parent process and make the handle non-inheritable. Then any child process will become part of the job, but only one handle exisst (the one owned by the parent). If the parent crashes then the handle is reclaimed by the OS and this will terminate the NT job object, killing all child processes as well as any grand-child or grand-grand-child process.
On Linux (and OS X) the same functionality is achieved with process groups.
I am not aware of any cross-platform library that would abstract this into a coherent uniform API.
Is it possible to create a windows service to create and maintain another process? Like I'm writing a program, and say a virus killed the process, could I have my window service running and basically 'watching' it? I already have the code for a regular application that stays running and executes a program if it's not currently running, to keep it running.
I've never written a service before, but would it be that hard to just write this simple program, which basically runs a check to see if the process is running, if not, it executes it and sleeps for a few minutes?
Thanks.
Yes, it is possible. It is not uncommon to see third-party apps have watchdog services to keep them running in case of crashes. A service can enumerate running processes using EnumProcesses(), and if the desired executable is not running then start a new copy of it using CreateProcessAsUser().
If the service is the one starting the executable process in the first place, or can find it after an enumeration, one optimization would be to keep an open handle to the process (returned by CreateProcess...(), or use OpenProcess() on the process ID an enumeration returns), and then use a wait function, like WaitForSingleObject(), to detect when the process stops running. That way, you don't have to enumerate processes to find out if the intended process is still running or not.
Is there some way to detect that a program was ended by windows task manager's "end process"?
I know that its kinda impossible to do that from within the application being ended (other than to build your app as a driver and hook ZwTerminateProcess), but I wonder if there is a way to notice it from outside.
I don't want to stop the program from terminating, just to know that it was ended by "end process" (and not by any other way).
There might be a better way - but how about using a simple flag?
Naturally, you'd have to persist this flag somewhere outside of the process/program's memory - like the registry, database, or file system. Essentially, when the app starts up, you set the flag to 'True' when the app shuts down through the normal means, you set the flag to 'False'.
Each time the application starts you can check the flag to see if it was not shut down correctly the previous time it was executed.
Open up a handle to the process with OpenProcess, and then wait on that handle using one of the wait functions such as WaitForSingleObject. You can get the exit status of the process using GetExitCodeProcess. If you need your program to remain responsive to user input while waiting, then make sure to wait on a separate thread (or you can periodically poll using a timeout of zero, but remember the performance consequences of polling -- not recommended).
When you're done, don't forget to call CloseHandle. The process object won't be fully deleted from the OS until all of its handles are closed, so you'll leak resources if you forget to call CloseHandle.
Note that there's no way to distinguish between a process exiting normally or being terminated forcefully. Even if you have a convention that your program only ever exits with a status of 0 (success) or 1 (failure) normally, some other process could call TerminateProcess(YourProcess, 1), and that would be indistinguishable from your ordinary failure mode.
According to the documentation, ExitProcess calls the entry point of all loaded DLLs with DLL_PROCESS_DETACH, whereas TerminateProcess does not. (Exiting the main function results in a call to ExitProcess, as do most unhandled exceptions.)
You might also want to look into Application Recovery and Restart.
One option might be to create a "watchdog" application (installed as a service, perhaps) that monitors WMI events for stopping a process via the ManagementEventWatcher class (in the System.Management namespace).
You could query for the death of your process on an interval or come up with some event driven way to alert of your process's demise.
Here's sort of an example (it's in C# though) that could get you started.
Is there some portable way to check the number of parallel instances of my app?
I have a c++ app (win32) where I need to know how often it was started. The problem is
that several user can start it parallel (terminal server), so i cannot search the "running process" list because I'm not able to access the the list of other users.
I tried it with Semaphore (boost & win32 CreateSemaphore)
It worked, but now I have the problem if the app crashes (Assertion or just kill the process) the counter is not changed. (rebooting helps)
Also manually removing/resetting the semaphore counter in my code is not possible because I don't know if somebody else is running my application.
Edited to add:
Suppose you have a license that lets you run 20 full-functionality copies of your program. Then you could have 20 mutexes, named MyProgMutex1 through MyProgMutex20. At startup, your program can loop through the mutexes. If it finds a spare mutex that it can take, it stops looping and enters full-functionality mode. If it loops through all the mutexes without being able to take any of them, then it enters reduced-functionality mode.
Original answer:
I assume you want to make sure that only one copy of your process runs at once. (Or, for Terminal Server, one copy of your process per login session).
Your named semaphore solution is close. The right way to do this is a named mutex. Use CreateMutex to make the mutex, then call WaitForSingleObject with a timeout of zero. If WaitForSingleObject returns WAIT_TIMEOUT, another copy of the process is running. If it returns WAIT_OBJECT_0 or WAIT_ABANDONED, then you are the only copy of the process. You need to keep the mutex handle open while your program runs - either call CloseHandle when your process is about to exit, or just deliberately leak the handle and rely on Window's built-in cleanup to release the handle for you when your process exits. Windows will automatically increment the mutex's counter when your process exits.
The only thing I can think of that mitigates the problem of crashed processes is a kind of “dead man’s switch”: each process needs to update its status in regular intervals. If a process fails to do this, it’s automatically discarded from the list of active processes.
This technique requires that one of the processes acts as a server which keeps tab of whether other processes have updated recently. If the server dies, then another process can take over. This, in turn, requires that each process tests whether there still is a server alive.
Alternatively, each process can be its own server and keep track locally. This may be easier to implement than server-switching.
You can broadcast message and other instances of your application should send some response. You count responses - you get number of instances.