WordPress takes measures to ensure that a cron task doesn’t run twice when it should run once, e.g. once every hour when an hourly schedule is given, rather than the occasional twice at the scheduled time.
While it’s not foolproof, what steps does WordPress take to make sure it happens at the scheduled times, and only once as specified?
A transient is set to reflect the state of the cron, which gets deleted when all tasks complete. Any subsequent requests are ignored if that transient is found…
onetrickpony’s answer is mostly correct. If you let WordPress do its default thing, or you manually trigger wp-cron by fetching its URL with ‘doing_wp_cron’ set to a unique value in the GET string, then you can reliably expect jobs to not be executed twice.
But if you execute wp-cron.php from the PHP CLI in your crontab, the story is different. Now it will check a constant called WP_CRON_LOCK_TIMEOUT to find out if it should ignore the lock that is stored in the transient. And there is a race condition that enables the same job to sometimes run twice.
If you want to be really sure the same job never executes twice, either don’t set DISABLE_WP_CRON or use curl or wget in your crontab to fetch wp-cron.php like so:
*/10 * * * * wget -q -O "http://www.example.com/wp-cron.php?doing_wp_cron=`date +\%s.\%N`" > /dev/null 2>&1
Also note that there was a bug in 3.3 that caused jobs to be run twice if two instances of wp-cron.php were launched in the same second. Now they would need to be launched in the same microsecond, which is still possible, but highly unlikely.