How to?
I tried a WaitingForSingleObject, GetExitCodeThread and etc., but when i kill thread with process explorer nothing happens.
while(true)
{
if(GetThreadId(this->hWatchThread) == 0) // Always return killed thread id!
break;
}
Upd:
When i kill thread, it stop working, but i can't get exit code or zero value from GetThreadId
When a thread is killed forcibly, e.g. from the task manager or from Process Explorer, that does not change the thread ID. The thread handle still exists because your process has not yet closed it. And the thread ID associated with that thread still exists. So GetThreadId will always return a non-zero value.
As for the exit code, you can't get a meaningful value for the exit code because the thread did not exit. It was killed. It never had a chance to set an exit code.
What you must do is use one of the wait functions, e.g. WaitForSingleObject, to wait on your thread handle. If that wait terminates because the thread was killed, then the wait function will return and report a successful wait and the thread exit code will be reported as 0. To the best of my knowledge you cannot discern by means of the Windows API that your thread was killed abnormally.
What you could do is use your own mechanism to indicate that termination was abnormal. Create a flag, owned by the thread, to record that termination was normal. Set the flag to false when the thread starts executing. When the thread terminates normally, set the flag to true. This way you can tell whether or not the thread was terminated abnormally by reading the value of that flag after the thread terminates.
If you want to do something after the thread has exited:
WaitForSingleObject(handle_to_your_thread,INFINITE);
MessageBox(NULL,"Thread has exited","Foo",MB_ICONINFORMATION);
Related
I need to stop a service when our program has been killed with the task manager.
I tried with std::signal(...) and _onexit(...) but it does not work.
I tried running ProcessMonitor so check a sort of signal I can catch, but I did not find one.
I tried with a:
auto serviceStopThread = QThread::create([](){
::WaitForSingleObject(::GetCurrentProcess(), INFINITE);
ServiceUtils::stopService();
});
serviceStopThread->start();
but it does nothing.
How can I do?
While the process is still alive, find the PID, and open it with OpenProcess. You’ll need at least SYNCHRONIZE permission.
Then wait for the handle to become signaled. For example, you can launch a new thread, and call WaitForSingleObject with INFINITE timeout. The handle becomes signaled as soon as the process quits, regardless on the reason.
React however you like but don’t forget to call CloseHandle when you’re done.
If you only want to react when the process is killed suddenly, send some message to your supervising process when the program exits gracefully, to disable the handling.
In my process I need to start/restart another process.
Currently I use a thread with a tiny stack size and the following code:
void startAndMonitorA()
{
while(true)
{
system("myProcess");
LOG("myProcess crashed");
usleep(1000 * 1000);
}
}
I feel like that's not best practice. I have no idea about the resources the std::system() call is blocking or wasting. I'm on an embedded Linux - so in general I try to care about resources.
One problematic piece is restarting immediately: if the child process fails to start that is going to cause 100% CPU usage. It may be a transient error in the child process (e.g. cannot connect to a server). It may be a good idea to add a least one second pause before trying to restart.
What system call does on Linux is:
Sets up signals SIGINT and SIGQUIT to be ignored.
Blocks signal SIGCHLD.
fork()
Child process calls exec() shell, passing the command line to the shell.
Parent process calls waitpid() that blocks the thread till the child process terminates.
Parent process restores its signal dispositions.
If you were to re-implement the functionality of system you would probably omit step 5 (along with steps 1, 2 and 6) to avoid blocking the thread and rely on SIGCHLD to get notified when the child process has terminated and needs to be restarted.
In other words, the bare minimum would be to set up a signal handler for SIGCHLD and call fork and exec.
The code as shown would be adequate for most circumstances. If you really care about resource usage, you should be aware that you are starting (and keeping around) a thread for each process you are monitoring. If your program has an event loop anyway, that kind of thing can be avoided at the cost of some additional effort (and an increase in complexity).
Implementing this would entail the following:
Instead of calling system(), use fork() and exec() to start the external program. Store its PID in a global table.
Set a SIGCHLD handler that notifies the event loop of the exit of a child, e.g. by writing a byte to a pipe monitored by the event loop.
When a child exits, run waitpid with the WNOHANG flag in a loop that runs for as long as there are children to reap. waitpid() will return the PID of the child that exited, so that you know to remove its PID from the table, and to schedule a timeout that restarts it.
In my program, it start a boost thread and keep the handler as a member of the main thread.
When user press the cancel button I need to check the started thread still running and if it is running need tho kill that specific thread. here is the pseudo code.
cheating thread
int i =1;
boost::thread m_uploadThread = boost::thread(uploadFileThread,i);
This is the method use to check if thread is still running, but it is not working
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(2);
if (this->uploadThread.timed_join(timeout)){
//Here it should kill the thread
}
The return value true means the thread is completed before the call times out. And looks like what you want is
if(!this->uploadThread.timed_join(timeout))
For stop your thread you can use:
my_thread.interrupt();
in order this to work you have to set an interruption point at the point you want the thread's function stops when you interrupt.
Note: the interruption by it self don't stop the thread it just set a flag and the when an interruption point is reached the thread is interrupted. If no interruption point is found, the thread don't stop.
You can also handle the interrupted exception boost::thread_interrupted that way you can do things depending on if the thread was interrupted or not.
For instance lets assume the next code is inside a thread function:
try
{
//... some important code here
boost::this_thread.interruption_poit(); // Setting interrutption point.
}
catch(boost::thread_interrupted&)
{
// Now you do what ever you want to do when
// the thread is interrupted.
}
I peek into my ancestor's code and found out a leak in the following situation:
1) Launch application
b) After application is launched, close the applicaiton within 4 secs
The leak message:
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {58509} client block at 0x016DFA30, subtype c0, 68 bytes long.
Subsequently, I went through the code, found out the suspicious point of cause at a 4secs of sleep at controlling function of worker thread.
The test program:
UINT InitThread(LPVOID pParam)
{
Sleep(4000); //4000 is the default value, it reads from a registry key.
CMyMFCTestProjectDlg* pTest = (CMyMFCTestProjectDlg*)pParam;
pTest->DoSomething();
return 0; //--> Exit thread
}
BOOL CMyMFCTestProjectDlg::OnInitDialog() {
...
AfxBeginThread(InitThread, this);
...
}
If I reduce/remove the sleep timer, the leak will be solved.
However, I would like to know how does it happen. Either due to worker thread or GUI thread termination? Will worker thread exits after GUI thread will cause this problem?
Anyone can cheer up my day by helping me to explain this? I'm lost....
It sounds like the worker thread is not given a chance to close itself properly after your app closes, since the process ends before it exits. The operating system is usually pretty good at cleaning up resources on its own, so it may not be a problem. However, it's probably best if you wait for that thread to exit before allowing the application to shut down. Though it sounds like that that will cause a 4 second delay in the shutdown of your app.
If that's unacceptable, you will have to add some mechanism to the thread, to receive the shutdown event from the apps main thread. For example, if you replace the worker threads "sleep", with a WaitForSingleObject of an event:
DWORD res = WaitForSingleObject(
shutdownEvent,
4000); // timeout
if(res == WAIT_OBJECT_0)
{
// received the shutdownEvent, exit
return 0;
}
// The delay has elapsed, continue with rest of thread.
. . .
Then, when your are shutting down in your main thread, set the event, then wait for the thread to exit, it should exit almost immediately:
SetEvent(this->shutdownEvent);
WaitForSingleObject(pThread->m_hThread, INFINITE); // pThread is returned from AfxBeginThread
You should shutdown your threads gracefully before your process goes away. You can either have the main thread wait for the other thread(s) to exit or have the main thread signal the other thread(s) to exit.
68 bytes?
If the application does actually shut down, ie. has disappeared from the task manager 'Applications' and 'Processes', and the only effect of this 'leak' is to issue a debug message on early close, just turn the debug off and forget about it.
It's likely an abberation of MFC shutdown, some struct that cannot be safely freed during shutdown and is left around for the OS to clean up.
With the 99.9% of apps that are not continually restarted/stopped, a 68-byte leak on shutdown, even if it was not cleaned up, would not influence the operation of a Windows machine in any noticeable way between the reboot intervals enforced every 'Patch Tuesday'.
I'm sure you have plenty more bugs with more serious effects to deal with. If not, you can have some of mine!
Rgds,
Martin
I am invoking several processes in my main and I can get the pid of that processes. Now I want to wait until all this processes have been finished and then clear the shared memory block from my parent process. Also if any of the process not finished and segfaulted I want to kill that process. So how to check from the pid of processes in my parent process code that a process is finished without any error or it gave broke down becoz of runtime error or any other cause, so that I can kill that process.
Also what if I want to see the status of some other process which is not a child process but its pid is known.
Code is appreciated( I am not looking for script but code ).
Look into waitpid(2) with WNOHANG option. Check the "fate" of the process with macros in the manual page, especially WIFSIGNALED().
Also, segfaulted process is already dead (unless SIGSEGV is specifically handled by the process, which is usually not a good idea.)
From your updates, it looks like you also want to check on other processes, which are not children of your current process.
You can look at /proc/{pid}/status to get an overview of what a process is currently doing, its either going to be:
Running
Stopped
Sleeping
Disk (D) sleep (i/o bound, uninterruptable)
Zombie
However, once a process dies (fully, unless zombied) so does its entry in /proc. There's no way to tell if it exited successfully, segfaulted, caught a signal that could not be handled, or failed to handle a signal that could be handled. Not unless its parent logs that information somewhere.
It sounds like your writing a watchdog for other processes that you did not start, rather than keeping track of child processes.
If a program segfaults, you won't need to kill it. It's dead already.
Use the wait and waitpid calls to wait for children to finish and check the status for some idea of how they exiting. See here for details on how to use these functions. Note especially the WIFSIGNALED and WTERMSIG macros.
waitpid() from SIGCHLD handler to catch the moment when application terminates itself. Note that if you start multiple processes you have to loop on waitpid() with WNOHANG until it returns 0.
kill() with signal 0 to check whether the process is still running. IIRC zombies still qualify as processes thus you have to have proper SIGCHLD handler for that to work.