Reputation: 2777
I have such a problem to design.
Two event A, B.
A will run every 3.2 seconds, B will run every 1.7 seconds,
I want to use usleep() to implement timing. And should I also fork 2 thread to count the time concurrently? Or, I just usleep 1.7 secdons, and then usleep 1.5 second? and goes on??? Which is better? And what other situations should I consider? Thanks.
Upvotes: 2
Views: 357
Reputation: 123
You could use Boosts asynchronous timers. In the linked example, there are two timer threads (one is the main thread) running concurrently at a set period, in this case, at the rate of once per second. To make them run at 3.2 and 1.7 seconds respectively, change the line which says:
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
to make it run every 3.2 seconds:
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::millisec(3200));
Upvotes: 3
Reputation: 14330
How long do the events take to run? If it's more than no time at all, sleeping between each one will mean the events won't run every x
seconds, where x
is the time you sleep for. For example, if the event takes 1.2 seconds and you sleep for 1.7, it will run every 2.9 seconds. Fluctuation in the time it takes will make it hard to determine when each event will run.
You can counteract this by either measuring the time taken and subtracting it from the time you want to wait (1.7 - 1.2 = 0.5
, so you sleep for 0.5 seconds), or by using three threads: one to run event A, one to run event B and one to do the timing. You can either create a thread for each event which terminates when the event completes, or you can have one or more permanent threads that accept jobs to run. The first option means you don't have to worry about concurrency (because concurrency is hard).
If there is any possibility of the events taking longer than you're waiting, you need to make sure you don't start event A again while it's still running from the previous iteration. If you're using a single thread and sleeping, this will be taken care of for you. If you do go down the route of multiple threads, you can avoid this by creating a queue and pushing jobs onto it, but then you need to make sure you don't create a massive queue of duplicate jobs, which you can do by either not queuing a job if it's already on the queue, or overwriting existing jobs for the same event (depending on whether later ones should trump earlier ones).
Upvotes: 3