Reading the function description curl_multi_wakeup: enter link description here
Calling this function only guarantees to wake up the current (or the
next if there is no current) curl_multi_poll call, which means it is
possible that multiple calls to this function will wake up the same
waiting operation.
I am confused by the phrase - "the same waiting operation". How's that?
That is, suppose I have a function curl_multi_poll() in event standby mode in thread "A".
Now, for example, I call the curl_multi_wakeup() function twice from thread "B" and thread "C".
And what happens judging by this phrase:
...function will wake up the same waiting operation.
It turns out that the function curl_multi_poll - wakes up only once ?
curl_multi_wakeup is meant to be used with a pool of threads waiting on curl_multi_poll.
What the document says is that if you call curl_multi_wakeup repeatedly, it will possibly wake up only a single thread, not necessarily one thread for each call to curl_multi_wakeup.
curl_multi_poll() is a relatively new call, designed to simplify "interrupting" threads waiting on curl_multi_poll(). Here's a good explanation:
https://daniel.haxx.se/blog/2019/12/09/this-is-your-wake-up-curl/
curl_multi_poll()
[is a] function which asks libcurl to wait for activity on any of the
involved transfers – or sleep and don’t return for the next N
milliseconds.
Calling this waiting function (or using the older curl_multi_wait() or
even doing a select() or poll() call “manually”) is crucial for a
well-behaving program. It is important to let the code go to sleep
like this when there’s nothing to do and have the system wake up it up
again when it needs to do work. Failing to do this correctly, risk
having libcurl instead busy-loop somewhere and that can make your
application use 100% CPU during periods. That’s terribly unnecessary
and bad for multiple reasons.
When ... something happens and the application for example needs to
shut down immediately, users have been asking for a way to do a wake
up call.
curl_multi_wakeup() explicitly makes a curl_multi_poll() function
return immediately. It is designed to be possible to use from a
different thread.
Related
I have a program structured like that: one thread that receives tasks and writes them to input queue, multiple which process them and write in output queue, one that responds with results from it. When queue is empty, thread sleeps for several milliesconds. Queue has mutex inside it, pushing does lock(), and popping does try_lock() and returns if there is nothing in queue.
This is processing thread for example:
//working - atomic bool
while (working) {
if (!inputQue_->pop(msg)) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
} else {
string reply = messageHandler_->handle(msg);
if (!reply.empty()) {
outputQue_->push(reply);
}
}
}
And the thing that I dont like is that the time since receiving task until responding, as i have measured with high_resolution_clock, is almost 0, when there is no sleeping. When there is sleeping, it becomes bigger.
I dont want cpu resources to be wasted and want to do something like that: when recieving thread gets task, it notifies one of the processing threads, that does wait_for, and when processing task is done, it notifies responding thread same way. As a result I think i will get less time spent and cpu resources will not be wasted. And I have some questions:
Will this work the way that I see it supposed to, and the only difference will be waking up on notifying?
To do this, I have to create 2 condition variables: first same for receiving thread and all processing, second same for all processing and responding? And mutex in processing threads has to be common for all of them or uniuqe?
Can I place creation of unique_lock(mutex) and wait_for() in if branch just instead of sleep_for?
If some processing threads are busy, is it possible that notify_one() can try to wake up one of them, but not the free thread? I need to use notify_all()?
Is it possible that notify will not wake up any of threads? If yes, does it have high probability?
Will this work the way that I see it supposed to, and the only difference will be waking up on notifying?
Yes, assuming you do it correctly.
To do this, I have to create 2 condition variables: first same for receiving thread and all processing, second same for all processing and responding? And mutex in processing threads has to be common for all of them or uniuqe?
You can use a single mutex and a single condition variable, but that makes it a bit more complex. I'd suggest a single mutex, but one condition variable for each condition a thread might want to wait for.
Can I place creation of unique_lock(mutex) and wait_for() in if branch just instead of sleep_for?
Absolutely not. You need to hold the mutex while you check whether the queue is empty and continue to hold it until you call wait_for. Otherwise, you destroy the entire logic of the condition variable. The mutex associated with the condition variable must protect the condition that the thread is going to wait for, which in this case is the queue being non-empty.
If some processing threads are busy, is it possible that notify_one() can try to wake up one of them, but not the free thread? I need to use notify_all()?
I don't know what you mean by the "free thread". As a general rule, you can use notify_one if it's not possible for a thread to be blocked on the condition variable that can't handle the condition. You should use notify_all if either more than one thread might need to be awoken or there's a possibility that more than one thread will be blocked on the condition variable and the "wrong thread" could be woken, that is, there could be at least one thread that can't do whatever it is that needs to be done.
Is it possible that notify will not wake up any of threads? If yes, does it have high probability?
Sure, it's quite possible. But that would mean no threads were blocked on the condition. In that case, no thread can block on the condition because threads must check the condition before they wait, and they do it while holding a mutex. To provide this atomic "unlock and wait" semantic is the entire purpose of a condition variable.
The mechanism you have is called polling. The thread repeatedly checks (polls) if there is data available. As you mentioned, it has the drawback of wasting time. (But it is simple). What you mentioned you would like to use is called a blocking mechanism. This deschedules the thread until the moment that work becomes available.
1) Yes (although I don't know exactly what you're imagining)
2) a) Yes, 2 condition variables is one way to do it. b) Common mutex is best
3) You would probably place those within pop, and calling pop would have the potential to block.
4) No. notify_one will only wake a thread that is currently waiting from having called wait. Also, if multiple are waiting, it is not necessarily guaranteed which will receive the notification. (OS/library dependent)
5) No. If 1+ threads are waiting, notify_one it is guaranteed to wake one. BUT if no threads are waiting, the notification is consumed (and has no effect). Note that under certain edge conditions, notify_one may actually wake more than one. Also, a thread may wake from wait without anyone having called notify_one ("Spurious wake up"). The fact that this can happen at all means that you always have to do additional checking for it.
This is called the producer/consumer problem btw.
In general, your considerations about condition variable are correct. My proposal is more connected to design and reusability of such functionality.
The main idea is to implement ThreadPool pattern, which has constructor with number of worker threads ,methods submitTask, shutdown, join.
Having such class, you will use 2 instances of pools: one multithreaded for processing, second (singlethreaded by your choice) for result sending.
The pool consists of Blocking Queue of Tasks and array of Worker threads, each performing the same "pop Task and run" loop.The Blocking Queue encapsulates mutex and cond_var. The Task is common functor.
This also brings your design to Task oriented approach, which has a lot of advantages in future of your application.
You are welcome to ask more questions about implementation details if you like this idea.
Best regards, Daniel
I have a C++ program that uses overlapped IO for network communication. The main thread has a loop that calls SleepEx(5, true);. There are also two TCP sockets. I assume that the completion callbacks are called during the alertable wait. Assume also that by the time SleepEx gets called both of my TCP connections have received some data. Now the question is what happens if the first completion callback takes longer than 5ms? Does the SleepEx return after calling the first callback or does it also call the second callback? In other words does the SleepEx guarantee to call ALL of the scheduled completion callbacks? This is not clear because the documentation says it will return when at least one of the events meet...
Your code must not assume that both APCs will be called before SleepEx() returns. Conversely, it must not assume that a pending APC will not be called simply because the specified wait period has expired.
The only behaviour that you can rely upon is that if one or more APCs are pending, at least one will be executed.
Generally speaking, best practice is to wait for APCs in a loop that does nothing else, using an infinite timeout in the wait. If you need to do something periodically, you can use a waitable timer to generate an APC periodically.
Alternatively, you can use WaitForSingleObjectEx() or WaitForMultipleObjectsEx() to detect when a waitable timer or other synchronization object is triggered, while still handling APCs.
However, if you must perform some periodic action that cannot be handled in an APC or be triggered by a synchronization object, you can use nested loops: the inner loop does nothing but call the wait repeatedly (with a timeout period reduced by however long the loop has already been running) and the outer loop performs the periodic action.
If you must perform some periodic action that cannot be delayed by pending APCs, you will need to do it in a separate thread. Note that because Windows is not a real-time OS, you will still not be able to guarantee that any given action will take place within any particular timeframe, although you can reduce the risk by increasing the thread priority.
I'm using a third party library which has a blocking function, that is, it won't return until it's done; I can set a timeout for that call.
Problem is, that function puts the library in a certain state. As soon as it enters that state, I need to do something from my own code. My first solution was to do that in a separate thread:
void LibraryWrapper::DoTheMagic(){
//...
boost::thread EnteredFooStateNotifier( &LibraryWrapper::EnterFooState, this );
::LibraryBlockingFunction( timeout_ );
//...
}
void LibraryWrapper::EnterFooState(){
::Sleep( 50 ); //Ensure ::LibraryBlockingFunction is called first
//Do the stuff
}
Quite nasty, isn't it? I had to put the Sleep call because ::LibraryBlockingFunction must definitely be called before the stuff I do below, or everything will fail. But waiting 50 milliseconds is quite a poor guarantee, and I can't wait more because this particular task needs to be done as fast as possible.
Isn't there a better way to do this? Consider that I don't have access to the Library's code. Boost solutions are welcome.
UPDATE: Like one of the answers says, the library API is ill-defined. I sent an e-mail to the developers explaining the problem and suggesting a solution (i.e. making the call non-blocking and sending an event to a registered callback notifying the state change). In the meantime, I set a timeout high enough to ensure stuff X is done, and set a delay high enough before doing the post-call work to ensure the library function was called. It's not deterministic, but works most of the time.
Would using boost future clarify this code? To use an example from the boost future documentation:
int calculate_the_answer_to_life_the_universe_and_everything()
{
return 42;
}
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost::unique_future<int> fi=pt.get_future();
boost::thread task(boost::move(pt));
// In your example, now would be the time to do the post-call work.
fi.wait(); // wait for it to finish
Although you will still presumably need a bit of a delay in order to ensure that your function call has happened (this bit of your problem seems rather ill-defined - is there any way you can establish deterministically when it is safe to execute the post-call state change?).
The problem as I understand it is that you need to do this:
Enter a blocking call
After you have entered the blocking call but before it completes, you need to do something else
You need to have finished #2 before the blocking call returns
From a purely C++ standpoint, there's no way you can accomish this in a deterministic way. That is without understanding the details of the library you're using.
But I noticed your timeout value. That might provide a loophole, maybe.
What if you:
Enter the blocking call with a timeout of zero, so that it returns immediately
Do you other stuff, either in the same thread or synchronized with the main thread. Perhaps using a barrier.
After #2 is verified to be done, enter the blocking call again, with the normal non-zero timeout.
This will only work if the library's state will change if you enter the blocking call with a zero timeout.
I am using WaitForSingleObject() function for implementing wait in my program.
WaitForSingleObject(eventToBeSigaled, timeOut);
all of us know that this function wait for the event to be signaled for the specified amount of time.
But I want to know that what happens when the event has already singled before entering to this call, at that time is the wait will fail(WAIT_FAILED)? Please answer this with proper reason. I want to know this little deeper.
Answer to your first question: if the event is already signaled, your Wait() would return immediately returning WAIT_OBJECT_0.
Second question: One of the circumstances WAIT_FAILED is returned is if the event handle is closed when Wait() is called. In this case, the OS scheduler won't be able to process the Wait() call and hence returns WAIT_FAILED.
Note that at the end of the day, the Wait() functions are a means for the user threads to pass the CPU back to the OS until a certain condition is met. Depending on your needs, you use one of the OS primitives as a condition (semaphore, mutex, events, etc). The OS scheduler in turn checks this condition to determine if your worker thread should be given CPU time slice thereby ensuring that all threads (and hence all processes) get a fair share of the system resources.
you should check it's documentation first, link
Remarks
The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters the wait state until the object is signaled or the time-out interval elapses.
The Mac build of my (mainly POSIX) application spawns a child thread that calls CFRunLoopRun() to do an event loop (to get network configuration change events from MacOS).
When it's time to pack things up and go away, the main thread calls CFRunLoopStop() on the child thread's run-loop, at which point CFRunLoopRun() returns in the child thread, the child thread exits, and the main thread (which was blocking waiting for the child thread to exit) can continue.
This appears to work, but my question is: is this a safe/recommended way to do it? In particular, is calling CFRunLoopStop() from another thread liable to cause a race condition? Apple's documentation is silent on the subject, as far as I can tell.
If calling CFRunLoopStop() from the main thread is not the solution, what is a good solution? I know I could have the child thread call CFRunLoopRunInMode() and wake up every so often to check a boolean or something, but I'd prefer not to have the child thread do any polling if I can avoid it.
In the case of CFRunLoopStop - if it could only be called safely on the current run loop, then it would not be necessary to pass it a parameter indicating which run loop to stop.
The presence of the parameter is a strong indication that its ok to use it to stop run loops other than the current run loop.
In particular, is calling CFRunLoopStop() from another thread [safe]?
Here's what Run Loop Management says:
The functions in Core Foundation are generally thread-safe and can be called from any thread.
So maybe CFRunLoopStop is safe. But I do worry about their use of the word “generally”. My rule is: If Apple doesn't say it's safe, you should assume it's not.
To err on the safe side, you might consider creating a run loop source, adding that to your run loop, and signaling that source when it's time to end the thread. That same document includes an example of a custom run loop source.