I am trying to start several processes as close to the same time as possible. A cronjob selects all items to be processed from the database a minute prior to the actual time these processes need to start, and then starts a child process for each record found.
As it can take several seconds to run through the database and spawn the child processes, I am trying to create a sleep or usleep delay so that each spawned child process starts as close as possible to the top of the next minute.
In testing, I have noticed some differences between the child start times returned by time() and microtime().
Here's the code I have to create the delay:
$unixtime_now = time();
$unixMicrotime_now = microtime(true);
$timeToStart = $unixtime_now + 2;
$timeToSleep = $timeToStart - $unixMicrotime_now;
$timeToSleep = number_format($timeToSleep,6);
$timeToSleep = str_replace('.','',$timeToSleep);
usleep ($timeToSleep);
$startedAtMicrotimeFloat = microtime(true);
$startedAtTime = time();
$date1 = date("H:i:s", $startedAtMicrotimeFloat);
$date2 = date("H:i:s", $startedAtTime);
echo "Unixtime Now = $unixtime_now<br />UnixMicroTime Now = $unixMicrotime_now<br />Time to Start = $timeToStart<br />Time to Sleep = $timeToSleep<br />Started at Time = $startedAtTime - $date2<br />Started at MicroTimeFloat = $startedAtMicrotimeFloat - $date1";
Note that I used 2 seconds rather than 60 seconds for the offset to facilitate speed in testing.
2 questions:
1) No matter how many times I run this, the times returned by time() are ALWAYS 1 second before the times returned by microtime(). For example:
Started at Time = 1555765444 - 09:04:04
Started at MicroTimeFloat = 1555765445.0002 - 09:04:05
This is probably a forest for the trees issue, but does anyone have an idea why this is or how I can resolve it?
2) Are there any drawbacks to having a usleep() delay that can be as long as 59 seconds? Would it be better to use sleep() and accept the the child processes might start at 1555765445.9999 - 09:04:05 rather than 1555765445.0002 - 09:04:05, or up to almost a full second later?
Thanks in advance.
Alan
Per Dave's suggestion, I edited the code as follows:
$date1 = date("H:i:s", microtime(true));
$date2 = date("H:i:s", time());
I still get the same result:
Started at Time = 1555876342 - 15:52:22
Started at MicroTimeFloat = 1555876343.0003 - 15:52:23
The microtime() result, which I suspect to be accurate, is later than the time() result by 1.0003 seconds.
Related
I have created two functions in a separate php file and want them to run over and over.
After function A completes, I want it to compare the current time, relative to the last time function B ran, and if more than 24hrs has elapsed (or whatever value I set it to), it runs function B, resets the next time for when it should be trigger to run, and continues to run function A. They need to run separately and not parallel since values altered in function A will affect function B and thus need to be separate. The ideal scenario is I have a config.php file where I set the time delay (in hours), but I can sort that out later!
I am stumped on how to get this while(true){} loop organized... any ideas?
Regardless of whether you end up doing it this way (because I think the comments about cron make some good points, and there are some other issues you may run into with a continuously running PHP script like this) here's a basic logic for executing the alternate function based on a defined delay.
// define the delay and initialize the timestamp
$delay = 86400; // 24 hours, for example
$last_time = time();
while (true) {
functionA();
// the next time functionB should execute is the timestamp for the last run + the delay
if (time() > $last_time + $delay) {
functionB();
$last_time = time(); // reset the timestamp
}
}
Would something of this nature be similar to what you're looking for?
while ($time > 13 && $time < 21)
You could have flags involved in each function as well. If a boolean flag is fired and is = 1, then continue on?
I am making a game mode in which I am trying to get the time a player has arrived at their destination after starting the mode and to do this I am using the insert of a date when it starts the mode it inserts a date and after reaching the your destination it registers another date and with both dates it calculates the time it took to get to the destination, with this I'm using date H:i:s (hours, minutes, seconds) but I need to take the time out and leave milliseconds after seconds example: i:s:u (minutes, seconds, milliseconds) but I'm not able to do this, I've tried it in several ways, basically everything works as follows:
1. I add in the player array a current date with hour, minutes, seconds;
$this->game[$player->getName()] = ["start" => strtotime('now')];
2. After the Player arrives at his destination he calculates the time of his trajectory creating another current date with already registered and using date and mktime to do the join and give a visual of time to the player;
$time = date('H:i:s', mktime(0, 0, str_replace("-", "", $this->game[$player->getName()]["start"] - strtotime('now'))));
3. Send the pretty message to the player about the time of his trajectory then time will be something like this: 01:45:23 (minute:seconds:milliseconds).
$player->sendMessage("You beat your time record by ".$time);
This is my method of doing, if you have another better method with the milli seconds added I accept the suggestion! Maybe there might be some errors in my code that I'm still not sure if they work correctly as the subtraction to calculate and join the current time with the previous one, tell me if it's right and if it is not correct correct me or do better. Thank you
Use microtime which returns the current Unix timestamp with microseconds
$game = [];
$game['start'] = microtime(true);
// Do stuff
sleep(3); // Without the sleep, start and end are the 'same'
$game['end'] = microtime(true);
$elapsedTime = ($game['end'] - $game['start']);
$minutes = floor($elapsedTime / 60);
$seconds = $elapsedTime % 60;
$milliseconds = number_format($elapsedTime - floor($elapsedTime),3);
I'm using a simple way to get a timer from the last action until now, with a cooldown to avoid exploit over a system I am programming.
I am using this formula:
$last_blood = $userRow['lastblood'];
$now_blood = time();
$cooldown_blood = 10800;
$timer_blood = $now_blood - $last_blood;
$next_blood = $cooldown_blood - $timer_blood;
$hours_blood = date("H:i:s", $next_blood);
The thing is that with 60M frame this cooldown system works like a charm, but this time I set it up to 10800 seconds (3 hours).
The $hours_blood keeps stating that I need to wait 1 more hour than the expected.
Results:
I am currently writing a online game. Now I have to check if an event happen (checking timestamp in database) and depending on that execute some actions. I have to check for an event every second.
I wanted to use a cronjob but with cron you can run a script only every minute.
My idea was to use cron and loop 60 times in my php script. But I think this isn't the best solution.
So whats the best way to run a script every second?
I searched for a better solution but it seems that my first idea, with clean code, is the best solution.
This is my current code:
<?php
set_time_limit(60);
$start = time();
for ($i = 0; $i < 59; ++$i) {
// Do whatever you want here
time_sleep_until($start + $i + 1);
}
?>
Why not modify the script so that it just repeats the code every second? This will reduce the parsing overhead and be less complicated.
You should probably run the script once, and use a loop with delay to accomplish your desired timing.
The side benefit is that this is more efficient, and you would only have to open resources (ie, databases) once.
You shouldn't want this :P. No host will accept your cronjob is running every second every minute?
You can save the time it runned in a database, and the next time you run it calculate the time between both runs and do the calculations you want. every second is a very bad idea.
$total_time = 0;
$start_time = microtime(true);
while($total_time < 60)
{
//DoSomethingHere;
echo $total_time."\n";
//sleep(5);
$total_time = microtime(true) - $start_time ;
}
add this in crontab to run every minute.
I'm executing a PHP script that takes about a minute to finish and although the default time limit is set to 30 seconds, the script continues its execution after that limit.
I found out, that the limit only affects the time that is spent inside the script itself and not the time spent in library functions like database queries etc.
Is there a way to find out the time that is actually spent inside the script? I tried to use getrusage, but it doesn't seem to return the appropriate values for this problem.
Example:
<?php
$time = microtime(TRUE);
sleep(100);
echo 'Time: ', microtime(TRUE) - $time;
?>
The script waits for 100 seconds and does not terminate after the time limit of 30 seconds.
According to the documentation of set_time_limit, the time that is spent inside the sleep function (100 seconds) is not involved in the calculation of the execution time, because it's an external (library) function.
I just want to know how much of the execution time is spent inside my script and how much is spent in library functions.
Use XDebug Profiler for it.
I'm guessing you want something like this:
<?php
// the whole operation
$time1 = time();
// perform some functions
$s = file_get_contents("somefilename");
$time2 = time();
// perform some library functions
$rs = some_third_party_library_function();
$time3 = time();
// Show results
echo "Overall Time spent: " . ($time3 - $time1) . "s <br>";
echo "Time spent reading file: ". ($time2 - $time1) . "s <br>";
echo "Time spent by Third Party Library: " . ($time3 - $time2) . "s <br>";
?>
You can mark the start time before entering the script, then mark the end time after the script ends. Echo the difference then.
<?php
$a=time();
sleep(5);
$b=time();
echo $b-$a;
?>
If you need to measure the execution time of individual functions vs standard or built-in PHP functions, this is best done with a proper debugger and code profiler. Xdebug does exactly that.
Don't know how complicated your script is, however you can just add a comment to all your library functions calls. If your code requires their returned values in order to be properly executed, replace them with constant values (that could have been returned by these functions). For example:
$result = mysql_query( ... )
replace with:
// $result = mysql_query( ... )
$result = // resource, boolean or whatever you want
Then run the script and calculate the execution time using Coding-Freak's suggestion.
If you prefer Rio Bautista's approach you may find some functions that calculates section's time.