Understanding WaitForSingleObject and WaitForMultipleObject - c++

I have a windows service where I am receiving http requests and launching a process for it which might run more than an hour . I need to get notified in main service when a process ends .And when service is ended i need to terminate all child processes . I understand that if I do waitforsingleobject it will hang on windows service until the process is completed , and no further http requests will be entertained ? I am doing following for now which works but its not correct approach .
if(CreateProcess( TEXT(EXEPATH),
procArguments,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi )
)
{
processHandles[processCount] = pi.hProcess;
processStreams[processCount] = eventId.c_str();
processCount++;
}
On Service stop I am doing this
for(int index=0;index<10;index++){
g_pAppLog->Log("Stop Process for processStreams[%d] %s\n",index,processStreams[index].c_str());
int terminationResult = TerminateProcess(processHandles[index],1);
}

The functions WaitForSingleObjectEx and WaitForMultipleObjectsEx allow you to specify a timeout, so that the function will not hang forever.
You can thus call the function in a loop, checking if the process has really terminated, or it's just a timeout expiration.
Anyway, you should not WaitFor anything, unless you have nothing better to do.
If you have a web server, you should listen to connection and spawn responding processes.
If you just want to check if a process terminated, you can call GetExitCodeProcess.
So, summing up, you might either:
Run a loop that:
accepts a request;
spawns a process;
checks if any of the previously created process terminated (without blocking);
Make a two-thread application, with one thread accepting requests, and the other one calling WaitForMultipleObjectsEx in a loop, and possibly handling children termination.

In your main service, you should create a thread to do that, so the main thread can still be running.. In this thread, you should use WaitforMultipleObjects to wait for all the child process to end, once a process is ended, the corresponding code will be execute.
Please check the MSDN for details

Do the waiting in a different thread than the one that is processing SCM requests. Use CreateEvent() to create a waitable manual-reset event, then have the waiting thread use WaitForMultipleObjects() to wait on both the event and the child process at the same time. WaitForMultipleObjects() will tell you which one is signaled first. When the service is being stopped, signal the event with SetEvent(). When the child process exits, its handle will be signaled. If the event gets signaled first, the waiting thread can call TerminateProcess() on the child process.

Related

C++ - Windows - catch process exit from Task Manager

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.

Linux best practice to start and watch another process

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.

C++ run a task in secondary thread and expect a response on main thread

I have to run a task in background using thread in C++. Actually in code i have to send multiple HTTP request using curl and i don't want to run using Main thread as it will put main thread blocked untill task is completed. Hence I want for each http request is should be something like that :
a) a new thread is created b) send the curl req on this new thread c) once req/response is done, send response/data back to main thread
During this process i want Main thread to be free and run some other its own task. I am new to C++ and threading, please advise how to achieve this.
If you want your main thread to be notified as soon as the worker thread is done then it sounds like you need to have a message processing loop in the main thread.
I'm just thinking this can be implemented the same way as the window procedure in WinAPI. Something along these lines.
cEvent event;
while( true )
{
event = GetNextEvent();
if( event.GetType() == APPQUIT )
{
break;
}
if( event.GetType() == SENDHHPTREQUEST )
{
// Create worker thread etc.
}
else if( event.GetType() == HTTPREQUESTCOMPLETED )
{
// Process HTTP request resuts.
}
...
}
The worker thread needs a way to send events to the main thread. And of course adding, removing events from the message queue must be thread-safe, i.e. protected with mutexes. And I guess all the data required to create a request or to process results of a request needs to be somehow packaged into cEvent.
You need to use a condition variable or auto or manual reset event to notify your main thread. You get your main thread to wait for this condition variable when you've started your secondary thread, and when the secondary thread is done, it signal's the flag which lets the main thread know it's done and can continue doing what it's doing.
if you are using c++11 standard, I had to make a "main thread caller" which takes a lambda of code and schedules it to call on main thread next time the screen updates (which is always on the main thread). Internally it uses a vector of lambdas and drains it every time update is called. If there is no lambdas, update is not scheduled. I use it extensively in my iOS/Droid production code.
you can get it here:
https://github.com/radif/emjCCMainThreadCaller

Windows Api Multi-threading Messages

I'm just curious as to to how to implement multi-threading without using a Windows API WaitFor* function that stops the program until the thread has returned. What's the point of using threads if they stop the main application from being resized or moved etc.?
Is there any form of windows messaging with threading, which will allow me to call my thread function and then return, and handle the return values of the thread when it finishes running?
If you want your UI thread to know when a task thread has finished it's task then you could have your task thread post a (custom - WM_USER and above) message to your main window (along with thread id plus the handle). And the window proc of the main window can know that a particular task thread has finished it's task. This way the UI thread does not have to wait actively (using WaitFor*) on the thread(s) object.
You can use MsgWaitForMultipleObjectsEx to wait for the thread to finish and also process messages at the same time.
Have a look at std::thread, boost::thread, just::thread, for multithreading in general for c++.
But about Windows messaging win32 and MFC, the MSDN states explicitely that it is not multithread, it is monothread. ( Undefined behaviour is to be expected if multithreading is used)
For asynchronous message emited in other thread than the main application window thread, you should use ::PostMessage(), that will insert message events in the monothread message pump of the mono threaded window.
WaitForSingleObject can be non-blocking, just pass zero timeout as second parameter:
// Check is thread has been finished
if(::WaitForSingleObject(threadHandle, 0) == WAIT_OBJECT_0)
{
// Process results
...
}
You will need to periodically check this condition, e.g. on timer or after processing any message in message loop.
Or you can use MsgWaitForMultipleObjectsEx. It will unblock and return when some message/input event occured in calling thread message queue.
As other answers mentioned there is another way - using Windows asynchronously posted message to signal that thread has done its work. This way has disadvantage - the working thread must know target window or thread to post message to. This dependency complicates design and raises issues about checking thread/window lifetime. To avoid it message broadcasting (PostMessage(HWND_BROADCAST,...))
can be used, but this is overkill for your case, I don't recommend it.

Visual c++ thread with mutex not blocking

I'm developing with VC2005, and I'm having a problem with a thread.
I have a thread that dequeue data from a queue and send it. But this thread send one petition and have to wait for the answer to send a new petition (I want to put a timeout to prevent a infinite timeout).
I have a thread like this:
while (true){
dequeue()
send()
WaitForSingleObject(ptClass->getMutex(),10000);
}
But this WaitForSingleObject never stops... I've init event like this:
HANDLE ghMutex = CreateEvent(NULL,FALSE, FALSE, "");
The idea is to block the thread to stop sending data, and when the answer comes, unblock this thread to send a new petition... Why never stops???
regards
This thread you have is waiting for the event to be SET to signaled so it can be woken up again. You have to set the event to signalled using SetEvent. Not sure where you'd do it, as I don't know your architecture, but that's what's missing.
The WaitForSingleObject is taking your thread out of CPU context, but it isn't being woken up again.
Your timeout of your Wait should be set to INFINITE if you want it to wait until the event has been set to signaled and you cannot guarantee that it will happen immediately.
You're not using a mutex, you're using a AutoResetEvent, but you have to set it!