I have a main thread and sub thread.
In subthread I sendmessage to main thread.
In main thread, I call this:
while( ::WaitForSingleObject(hThread, 0) == WAIT_TIMEOUT )
{
MSG message;
while( ::PeekMessage( &message, NULL , WM_MIN, WM_MAX, PM_NOREMOVE ) )
{
::AfxPumpMessage();
}
}
It works fine!. But I dont know How does AfxPumpMessage() work? How to it avoid deadlock?
Anyone help me? Thanks in advance.
Your code runs a busy loop. The outer while loop terminates when the thread is signaled. Until then the loop runs busy and dispatches messages. This is what allows the main thread to wait on the sub-thread, but also respond to the messages that the sub-thread sends.
In fact, the call to PeekMessage is rather pointless. It is pointless because AfxPumpMessage will do the same, and pump all queued messages.
As I said, your outer loop is a busy loop. You really don't want that. There's no point consuming CPU cycles to do nothing. Instead of WaitForSingleObject, you should use MsgWaitForMultipleObjects. This allows you to wait on the thread, and be able to dispatch messages.
Assuming that you don't want to deal with queued messages, and only want to dispatch the sent messages, your loop might look like this:
while( ::MsgWaitForMultipleObjects(1, &hThread, FALSE, INFINITE,
QS_SENDMESSAGE) == WAIT_OBJECT_0 + 1 )
{
MSG message;
::PeekMessage(&message, 0, 0, 0, PM_NOREMOVE);
}
This won't deal with an queued messages. If you do need to process those, then the loop would look a little different.
Related
What is the best way to handle an interrupt signal in infinite loop in server application?
I develop simple FTP Server where every client has its own thread. And now, what I want to do is to handle interrupt signal and then interrupt every thread in the vector of client threads.
In every thread I want to have an opportunity to send to client some response while sending/receiving some file and manually close socket. In main thread I want to only log that server was aborted and close server socket.
I had an idea to implement my server class FTPServer like singleton and in signal() call a function which calls method abort() of FTPServer instance. But I don't know what it will do when the main infinite loop is still running and accept() is still waiting for a new client ... And this pattern I can not use in client threads because there are not only one instance ..
My methods are:
void FTPServer::run() {
while ( 1 ){
int cliFd = TCPController::acceptClient ( m_serverFD );
serveNewClient(cliFd);
}
}
void FTPServer::serveNewClient( int clientFD ){
m_client_threads.push_back( thread(&FTPServer::clientThread, *this, clientFD) );
}
void FTPServer::clientThread( int clientFD ){
ClientThread client(clientFD);
client.run();
}
So I want to handle interrupt signal, break(?) the main infinite loop and call abort() method.
I was searching for something like this:
void FTPServer::run() {
try{
while ( 1 ){
int cliFd = TCPController::acceptClient ( m_serverFD );
serveNewClient(cliFd);
}
catch( RuntimeException & e ){
this.abort()
}
}
But I didn't find anything .. :(
In every client thread I have infinite loop too - it waits for client's commands ...
So, please, can you tell me, what is the best way to handle it?
Thank you !
You have multiple threads, each with its own loop. What you should do is make sure your thread loops frequently check to see if they should be aborted. So instead of blocking indefinitely on acceptClient, accept a connection with a timeout. When the timeout expires, or when a connection is accepted, check if the thread should quit.
I'm doing some event handling with C++ and pthreads. I have a main thread that reads from event queue I defined, and a worker thread that fills the event queue. The queue is of course thread safe.
The worker thread have a list of file descriptors and create an epoll system call to get events on those file descriptors. It uses epoll_wait to wait for events on the fd's.
Now the problem. Assuming I want to terminate my application cleanly, how can I cancel the worker thread properly? epoll_wait is not one of the cancellation points of pthread(7) so it cannot react properly on pthread_cancel.
The worker thread main() looks like this
while(m_WorkerRunning) {
epoll_wait(m_EpollDescriptor, events, MAXEVENTS, -1);
//handle events and insert to queue
}
The m_WorkerRunning is set to true when the thread starts and it looks like I can interrupt the thread by settings m_WorkerRunning to false from the main thread. The problem is that epoll_wait theoretically can wait forever.
Other solution I though about is: instead of waiting forever (-1) I can wait for example X time slots, then handle properly no-events case and if m_WorkerRunning == false then exit the loop and terminate the worker thread cleanly. The main thread then sets m_WorkerRunning to false, and sleeps X. However I'm not sure about the performance of such epoll_wait and also not sure what would be the correct X? 500ms? 1s? 10s?
I'd like to hear some experienced advises!
More relevant information: the fd's I'm waiting events on, are devices in /dev/input so technically I'm doing some sort of input subsystem. The targeted OS is Linux (latest kernel) on ARM architecture.
Thanks!
alk's answer above is almost correct. The difference, however, is very dangerous.
If you are going to send a signal in order to wake up epoll_wait, never use epoll_wait. You must use epoll_pwait, or you might run into a race with your epoll never waking up.
Signals arrive asynchronously. If your SIGUSR1 arrives after you've checked your shutdown procedure, but before your loop returns to the epoll_wait, then the signal will not interrupt the wait (as there is none), but neither will the program exit.
This might be very likely or extremely unlikely, depending on how long the loop takes in relation to how much time is spent in the wait, but it is a bug one way or the other.
Another problem with alk's answer is that it does not check why the wait was interrupted. It might be any number of reasons, some unrelated to your exit.
For more information, see the man page for pselect. epoll_pwait works in a similar way.
Also, never send signals to threads using kill. Use pthread_kill instead. kill's behavior when sending signals is, at best, undefined. There is no guarantee that the correct thread will receive it, which might cause an unrelated system call to be interrupted, or nothing at all to happen.
You could send the thread a signal which would interupt the blocking call to epoll_wait(). If doing so modify your code like this:
while(m_WorkerRunning)
{
int result = epoll_wait(m_EpollDescriptor, events, MAXEVENTS, -1);
if (-1 == result)
{
if (EINTR == errno)
{
/* Handle shutdown request here. */
break;
}
else
{
/* Error handling goes here. */
}
}
/* Handle events and insert to queue. */
}
A way to add a signal handler:
#include <signal.h>
/* A generic signal handler doing nothing */
void signal_handler(int sig)
{
sig = sig; /* Cheat compiler to not give a warning about an unused variable. */
}
/* Wrapper to set a signal handler */
int signal_handler_set(int sig, void (*sa_handler)(int))
{
struct sigaction sa = {0};
sa.sa_handler = sa_handler;
return sigaction(sig, &sa, NULL);
}
To set this handler for the signal SIGUSR1 do:
if (-1 == signal_handler_set(SIGUSR1, signal_handler))
{
perror("signal_handler_set() failed");
}
To send a signal SIGUSR1 from another process:
if (-1 == kill(<target process' pid>, SIGUSR1))
{
perror("kill() failed");
}
To have a process send a signal to itself:
if (-1 == raise(SIGUSR1))
{
perror("raise() failed");
}
I have a class which reads from a message queue. Now this class has also got a thread inside it. Depending on the type of the msg in msg q, it needs to execute different functions inside that thread as the main thread in class always keeps on waiting on msg q. As soon as it reads a message from queue, it checks its type and calls appropriate method to be executed in thread and then it goes back to reading again(reading in while loop).
I am using boost message q and boost threads
How can I do this.
Its something like this:
while(!quit) {
try
{
ptime now(boost::posix_time::microsec_clock::universal_time());
ptime timeout = now + milliseconds(100);
if (mq.timed_receive(&msg, sizeof(msg), recvd_size, priority, timeout))
{
switch(msg.type)
{
case collect:
{
// need to call collect method in thread
}
break;
case query:
{
// need to call query method in thread
}
break;
and so on.
Can it be done?
If it can be done, then what happens in the case when thread is say executing collect method and main thread gets a query message and wants to call it.
Thanks in advance.
Messages arriving while the receiving thread is executing long operations will be stored for later (in the queue, waiting to be processed).
If the thread is done with its operation, it will come back and call the receive function again, and immediately get the first of the messages that arrived while it was not looking and can process it.
If the main thread needs the result of the message processing operation, it will block until the worker thread is done and delivers the result.
Make sure you do not do anything inside the worker thread that in turn waits on the main thread's actions, otherwise there is the risk of a deadlock.
I have this piece of code in a secondary thread:
DWORD result = WaitForSingleObject(myhandle,10000);
if(result == WAIT_OBJECT_0){
AfxMessageBox(_T(...));
}
else if(result == WAIT_TIMEOUT){
AfxMessageBox(_T("Timeout"));
}
Sometimes, not always, the timeout will get called almost as soon as the WaitForSingleObject is called (not even 1s delay).
Am I doing something wrong ? Any suggestions for more stable alternatives ?
EDIT:
myhandle is created inside a class constructor as:
myhandle = CreateEvent(NULL,FALSE,FALSE,_T("myhandle"));
it would get called by another function:
SetEvent(myhandle);
The point is it works when I do the SetEvent, the problem is that it sometimes times out as soon as the WaitForSingleObject is called, even though it should wait 10s.
Do you really need/want a named event? Typically this is only required for inter-process concurrency control.
If you have multiple instances of this class they will all use the same event - see the docs for CreateEvent about calling for a named object that already exists.
It may be that all you need to do is remove the name here. This allows each class instance to have its own Event object and behaviour should be more predictable.
WaitForSingleObject will not wait the whole 10 seconds. It will wait for the first of:
The timeout value is elapsed
The event is signaled
The handle becomes invalid (closed in another thread)
If the event is set when you call WaitForSingleObject, condition #2 is true from the start and WaitForSingleObject returns immediatly.
If you want to always wait 10 seconds, you should use code like this :
//Always wait 10 seconds
Sleep(10000);
//Test the event without waiting
if(WaitForSingleObject(myhandle, 0) == WAIT_OBJECT_0) {
AfxMessageBox(_T("Event was set in the last 10 secondes"));
} else {
AfxMessageBox(_T("Timeout"));
}
Took awhile but the problem actually was that the program sometimes did multiple calls to WaitForSingleObject. So it's a previous call that is timing out.
Solution is to use WaitForMultipleObjects and set a cancelling event in the case it is known that the first event won't be set, so the timer is cancelled before is it re-invoked.
In my main dialog I have a function that creates a process and waits for it to finish. It might take up to 15-20 seconds. If I simply wait using WaitForSingleObject my dialog becomes unresponsive.
I want to use a combination of EnableWindow(FALSE), and an internal message loop to make my dialog block, but without looking like the app freezes, the way MessageBox and DoModal do. But I'm not sure how to do that an internal message loop.
I'm afraid your approach won't work. Your app is single-threaded, or at least your UI is. After you call WaitForSingleObject your thread is put to sleep and it won't process windows messages. The fact that you have an internal message loop won't matter. You should probably start a new thread and use it to wait for the process to finish, then notify your UI thread and exit. Or something along those lines.
Running internal message loop is rather trivial coding.
Something like below is all:
EnableWindow(FALSE);
while ( /* check for my exit condition */ )
{
MSG msg;
if(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if( !AfxGetApp()->PumpMessage() )
{
::PostQuitMessage(0);
}
}
}
EnableWindow(TRUE);
To wait for the process exit, you could use very short(<30ms) timeout WaitForSingleObject call in the message loop. Or MsgWaitForMultipleObjects. Or GetExitCodeProcess.
I'd like to recommend another approach.
1) Show new modal popup
2) Start the process in OnInitDialog handler and start a timer
3) Check if the process is still running in OnTimer handler, by GetExitCodeProcess
4) Call EndDialog when the process is no longer running
Try MsgWaitForMultipleObjects function; it can process Windows messages while waiting for the event object.
You could:
(a bit complicated) use MsgWaitForMultipleObjects (or MsgWaitForMultipleObjectsEx) to wait for the process to finish or for a message to arrive (processing it in the normal way).
(simple) use RegisterWaitForSingleObject to register a callback that is called in a separate thread when the process exits (and perhaps have that callback just post a message to your window).
(fairly simple) create your own thread to do the waiting in.
I'd go with the 2nd option.
DWORD ec;
if(CreateProcess( NULL, // No module name (use command line).
szExe, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
procFlags, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
while(GetExitCodeProcess(pi.hProcess, &ec) && ec == STILL_ACTIVE)
{
MSG msg;
while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!AfxGetApp()->PumpMessage())
{
::PostQuitMessage(0);
break;
}
}
// let MFC do its idle processing
LONG lIdle = 0;
while(AfxGetApp()->OnIdle(lIdle++))
;
}
}
if(ec)
{
CloseHandle(pi.hProcess);
}