I am working in a kind of "control block" that has to send a flag each 6 minutes. The thing is that I don't know if there is a simple way of doing this. I have had though in use clock_t inside a loop till it reaches the 6 minutes, and then call a method that sends the flag and re-initialize the clock_t variable.
I forgot to explain something, sleep is not an option because the block works like a flow, it has to send something the whole time. Actually the flag will change what is sending
Thanks in advance
You can just sleep the thread for 6 minutes and then send the flag:
for(;;)
{
sendFlag();
sleep(6*60);
}
Here are some options for the sleep method, including C++11's std::this_thread::sleep_for.
You could simply use a thread function that switches a flag on or off and sleep it for 6 minutes at a time. For example:
bool flag = false;
int main() {
while(true) {
if (flag == true) {
flag = false;
}
}
return(0);
}
void threadFunc() {
flag = true;
sleep(360); //360 seconds is 6 minutes
}
NOTE: You will need to use a mutex or semaphore because the code written now is not thread safe. How you use threads is also operating system dependent. Unless you use C++11 of course.
You don't need a whole thread just for this. Use a system OS periodic timer callback.
Related
I've implemented code to call a service API every 10 seconds using a c++ client. Most of the times I've noticed it is around 10 seconds but occassionally I see an issue like below where it look longer. I'm using conditional variable on wait_until. What's wrong with my implementation? Any ideas?
Here's the timing output:
currentDateTime()=2015-12-21.15:13:21
currentDateTime()=2015-12-21.15:13:57
And the code:
void client::runHeartbeat() {
std::unique_lock<std::mutex> locker(lock);
for (;;) {
// check the current time
auto now = std::chrono::system_clock::now();
/* Set a condition on the conditional variable to wake up the this thread.
This thread is woken up on 2 conditions:
1. After a timeout of now + interval when we want to send the next heartbeat
2. When the client is destroyed.
*/
shutdownHeartbeat.wait_until(locker, now + std::chrono::milliseconds(sleepMillis));
// After waking up we want to check if a sign-out has occurred.
if (m_heartbeatRunning) {
std::cout << "currentDateTime()=" << currentDateTime() << std::endl;
SendHeartbeat();
}
else {
break;
}
}
}
You might want to consider using the high_resolution_clock for your needs. system_clock is not guaranteed a high resolution, so that may be a part of the problem.
Note that it's definition is implementation dependent so you might just get a typedef back onto system_clock on some compilers.
I am looking for a way to execute some code every X seconds but if an event occurs during the X seconds, break immediately.
Originally I had a while loop with a sleep statement at the end. However this was problematic because if the code was sleeping, I couldnt stop the code immediately and had to wait until the sleep had finished.
Is there any simple way I can execute then sleep, but interrupt this sleep on an event?
EDIT: Opted for a condition variable with notify_all().
You seem to have already found out an answer but conditional wait on mutex is the best solution here. You can essentially lock the mutex and throw it in a wait condition object along with some timeout. Some other thread can then signal/notify your thread using the same (shared) wait condition object. If nobody notifies/signals the mutex within specified timeout, the wait will simply come out of sleep.
The advantage of this interruptible sleep is that it's not a busy waiting.
I don't think you can interrupt sleep but you could have your code sleeping in shorter intervals and check for a signal regularly.
#include <thread>
#include <chrono>
int main()
{
using namespace std::chrono;
unsigned Y = 100;
unsigned X = 1;
bool signaled = false;
while (!signaled)
{
// Do Stuff every X seconds
high_resolution_clock::time_point const p = high_resolution_clock::now();
while (duration_cast<milliseconds>(high_resolution_clock::now() - p).count() <
duration_cast<milliseconds>(std::chrono::seconds(X)).count())
{
// Code to check for a signal every Y milliseconds
if (signaled)
{
break;
}
std::this_thread::sleep_for(milliseconds(Y));
}
}
return 0;
}
Note: System depedant clock resolutions; Possible trade-off with respect to CPU load when adjusting signal check frequency (depending on the demand of the signal check code);
I'm in a worker thread and want to sleep for a specified period of time (usually a few hundreds milliseconds), but the sleep should be interruptible. Here is what I have come up with
void DummyScope::sleepForSamples() {
if(m_sampleSleep < 100) {
MySleeper::sleep(m_sampleSleep);
return;
}
// sleep in periods of 100 ms, to be responsible for shutdown requests
qint64 t = QDateTime::currentMSecsSinceEpoch();
qint64 end = t + m_sampleSleep;
while(t + 100 <= end) {
MySleeper::sleep(100);
t = QDateTime::currentMSecsSinceEpoch();
// TODO: check here whether we are interrupted
}
if(end > t) {
MySleeper::sleep(end - t);
}
}
However that looks a bit convoluted and I wonder whether there's a better way to do this. Is using a QWaitCondition with a timeout-wait a better solution?
'Is using a QWaitCondition with a timeout-wait a better solution?'
Yes!
The sleep() loop, apart from needlessly running every 100ms, has an average 'interrupt' latency of 50ms.
Definitely wait on a condition variable and let the accompanying condition tell you why you were interrupted.
If you don't have to use QT-threads, c++11 and boost let you add a predicate to wait_for/timed_wait, so spurious wakeups don't mess with your timeout.
Of course, it is even more convienent if you can go 1 step further and don't bother with a timeout (if the condition variable can handle all cases).
You can wait directly on the mutex with QMutex::tryLock(int timeout), if you lock and unlock it from another thread.
I'm working on a little threading library and have run into a problem. boost::condition_variable.wait() works perfectly, however boost::condition_variable.timed_wait() returns immediately, it doesn't time out.
The documentation says it should only return once the timeout has passed or it's been notified. It's a three second wait before notification and I've tried both 10 second and 100 second timouts, so it should return after 3 seconds.
EDIT:
boost::condition_variable waitCondition;
boost::mutex mMutex;
Message MessageClient::waitAsync(Message msg, bool waitForReply) {
unique_lock<boost::mutex> lock(msg->mMutex);
if(mSendTimeout.sec == 0)
msg->waitCondition.wait(lock);
else {
timeout = msg->waitCondition.timed_wait(lock, mSendTimeout);
if(!timeout)
return 0;
if(waitForReply) {
Message reply = receiveMessage();
return reply;
}
else
return 0;
}
This is called after a sendMessage. The receiver get the message, sends the reply and then calls
waitCondition.notify_all();
Condition variable waits can occasionally result in spurious wakeups. As such, you must use them in a loop:
while (someCondition)
msg->waitCondition.wait(lock);
With timed_wait it's slightly more complex as you must recalculate your timeout to deal with however long it did, in fact, wait. Boost offers a variant with a predicate that, given an absolute timeout, will do the loop for you:
msg->waitCondition.timed_wait(lock, absoluteTimeout, boost::lambda::var(someFlag));
If you're still having problems, check that mSendTimeout is not negative or very small, and consider the use of an absolute timeout.
Today i got a idea to make an ThreadQueue for C++, for my Server Application.
unsigned int m_Actives; // Count of active threads
unsigned int m_Maximum;
std::map<HANDLE, unsigned int> m_Queue;
std::map<HANDLE, unsigned int>::iterator m_QueueIt;
In an extra Thread i would to handle these while:
while(true)
{
if(m_Actives != m_Maximum)
{
if(m_Queue.size() > 0)
{
uintptr_t h = _beginthread((void(__cdecl*)(void*))m_QueueIt->first, 0, NULL);
m_Actives++;
}
else
{
Sleep(100); // Little Cooldown, should it be higher? or lower?
}
}
}
m_Maximum is setable and is the Maximal Thread Count. I think that should work, but now i need to Wait foreach Thread which is active and need to check if its finished/alive or not. But for this i would use WaitForSingleObject. But then i need 1 Thread per Thread. So 2 Threads. In the one something get handled. In the other one it wait for the 1 Thread to exit.
But i think that realy bad. What would you do?
You can use WaitForMultipleObjects to wait while any of started threads is ended.
Or, what is probably better in this case in each thread you can send an EVENT before stopping it. Than, the monitor thread should only wait and process this event.
But, to be honest, your description and source is rather tricky....