.TH timer 3erl "stdlib 5.2" "Ericsson AB" "Erlang Module Definition" .SH NAME timer \- Timer functions. .SH DESCRIPTION .LP This module provides useful functions related to time\&. Unless otherwise stated, time is always measured in \fImilliseconds\fR\&\&. All timer functions return immediately, regardless of work done by another process\&. .LP Successful evaluations of the timer functions give return values containing a timer reference, denoted \fITRef\fR\&\&. By using \fIcancel/1\fR\&, the returned reference can be used to cancel any requested action\&. A \fITRef\fR\& is an Erlang term, which contents must not be changed\&. .LP The time-outs are not exact, but are \fIat least\fR\& as long as requested\&. .LP Creating timers using erlang:send_after/3 and erlang:start_timer/3 is more efficient than using the timers provided by this module\&. However, the timer module has been improved in OTP 25, making it more efficient and less susceptible to being overloaded\&. See the Timer Module section in the Efficiency Guide\&. .SH DATA TYPES .nf \fBtime()\fR\& = integer() >= 0 .br .fi .RS .LP Time in milliseconds\&. .RE .nf \fBtref()\fR\& .br .fi .RS .LP A timer reference\&. .RE .SH EXPORTS .LP .nf .B apply_after(Time, Module, Function, Arguments) -> .B {ok, TRef} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Module = module() .br Function = atom() .br Arguments = [term()] .br TRef = tref() .br Reason = term() .br .RE .RE .RS .LP Evaluates \fIspawn(Module, Function, Arguments)\fR\& after \fITime\fR\& milliseconds\&. .LP Returns \fI{ok, TRef}\fR\& or \fI{error, Reason}\fR\&\&. .RE .LP .nf .B apply_interval(Time, Module, Function, Arguments) -> .B {ok, TRef} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Module = module() .br Function = atom() .br Arguments = [term()] .br TRef = tref() .br Reason = term() .br .RE .RE .RS .LP Evaluates \fIspawn(Module, Function, Arguments)\fR\& repeatedly at intervals of \fITime\fR\&, irrespective of whether a previously spawned process has finished or not\&. .LP .RS -4 .B Warning: .RE If the execution time of the spawned process is, on average, greater than the given \fITime\fR\&, multiple such processes will run at the same time\&. With long execution times, short intervals, and many interval timers running, this may even lead to exceeding the number of allowed processes\&. As an extreme example, consider \fI[timer:apply_interval(1, timer, sleep, [1000]) || _ <- lists:seq(1, 1000)]\fR\&, that is, 1,000 interval timers executing a process that takes 1s to complete, started in intervals of 1ms, which would result in 1,000,000 processes running at the same time, far more than a node started with default settings allows (see the System Limits section in the Effiency Guide)\&. .LP Returns \fI{ok, TRef}\fR\& or \fI{error, Reason}\fR\&\&. .RE .LP .nf .B apply_repeatedly(Time, Module, Function, Arguments) -> .B {ok, TRef} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Module = module() .br Function = atom() .br Arguments = [term()] .br TRef = tref() .br Reason = term() .br .RE .RE .RS .LP Evaluates \fIspawn(Module, Function, Arguments)\fR\& repeatedly at intervals of \fITime\fR\&, waiting for the spawned process to finish before starting the next\&. .LP If the execution time of the spawned process is greater than the given \fITime\fR\&, the next process is spawned immediately after the one currently running has finished\&. Assuming that execution times of the spawned processes performing the applies on average are smaller than \fITime\fR\&, the amount of applies made over a large amount of time will be the same even if some individual execution times are larger than \fITime\fR\&\&. The system will try to catch up as soon as possible\&. For example, if one apply takes \fI2\&.5*Time\fR\&, the following two applies will be made immediately one after the other in sequence\&. .LP Returns \fI{ok, TRef}\fR\& or \fI{error, Reason}\fR\&\&. .RE .LP .nf .B cancel(TRef) -> {ok, cancel} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 TRef = tref() .br Reason = term() .br .RE .RE .RS .LP Cancels a previously requested time-out\&. \fITRef\fR\& is a unique timer reference returned by the related timer function\&. .LP Returns \fI{ok, cancel}\fR\&, or \fI{error, Reason}\fR\& when \fITRef\fR\& is not a timer reference\&. .RE .LP .nf .B exit_after(Time, Reason1) -> {ok, TRef} | {error, Reason2} .br .fi .br .nf .B exit_after(Time, Target, Reason1) -> {ok, TRef} | {error, Reason2} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Target = pid() | (RegName :: atom()) .br TRef = tref() .br Reason1 = Reason2 = term() .br .RE .RE .RS .LP \fIexit_after/2\fR\& is the same as \fIexit_after(Time, self(), Reason1)\fR\&\&. .LP \fIexit_after/3\fR\& sends an exit signal with reason \fIReason1\fR\& to \fITarget\fR\&, which can be a local process identifier or an atom of a registered name\&. Returns \fI{ok, TRef}\fR\& or \fI{error, Reason2}\fR\&\&. .RE .LP .nf .B hms(Hours, Minutes, Seconds) -> MilliSeconds .br .fi .br .RS .LP Types: .RS 3 Hours = Minutes = Seconds = MilliSeconds = integer() >= 0 .br .RE .RE .RS .LP Returns the number of milliseconds in \fIHours + Minutes + Seconds\fR\&\&. .RE .LP .nf .B hours(Hours) -> MilliSeconds .br .fi .br .RS .LP Types: .RS 3 Hours = MilliSeconds = integer() >= 0 .br .RE .RE .RS .LP Returns the number of milliseconds in \fIHours\fR\&\&. .RE .LP .nf .B kill_after(Time) -> {ok, TRef} | {error, Reason2} .br .fi .br .nf .B kill_after(Time, Target) -> {ok, TRef} | {error, Reason2} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Target = pid() | (RegName :: atom()) .br TRef = tref() .br Reason2 = term() .br .RE .RE .RS .LP \fIkill_after/1\fR\& is the same as \fIexit_after(Time, self(), kill)\fR\&\&. .LP \fIkill_after/2\fR\& is the same as \fIexit_after(Time, Target, kill)\fR\&\&. .RE .LP .nf .B minutes(Minutes) -> MilliSeconds .br .fi .br .RS .LP Types: .RS 3 Minutes = MilliSeconds = integer() >= 0 .br .RE .RE .RS .LP Returns the number of milliseconds in \fIMinutes\fR\&\&. .RE .LP .nf .B now_diff(T2, T1) -> Tdiff .br .fi .br .RS .LP Types: .RS 3 T1 = T2 = erlang:timestamp() .br Tdiff = integer() .br .RS 2 In microseconds .RE .RE .RE .RS .LP Calculates the time difference \fITdiff = T2 - T1\fR\& in \fImicroseconds\fR\&, where \fIT1\fR\& and \fIT2\fR\& are time-stamp tuples on the same format as returned from \fIerlang:timestamp/0\fR\& or \fIos:timestamp/0\fR\&\&. .RE .LP .nf .B seconds(Seconds) -> MilliSeconds .br .fi .br .RS .LP Types: .RS 3 Seconds = MilliSeconds = integer() >= 0 .br .RE .RE .RS .LP Returns the number of milliseconds in \fISeconds\fR\&\&. .RE .LP .nf .B send_after(Time, Message) -> {ok, TRef} | {error, Reason} .br .fi .br .nf .B send_after(Time, Destination, Message) -> .B {ok, TRef} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Destination = .br pid() | .br (RegName :: atom()) | .br {RegName :: atom(), Node :: node()} .br Message = term() .br TRef = tref() .br Reason = term() .br .RE .RE .RS .RS 2 .TP 2 .B \fIsend_after/3\fR\&: Evaluates \fIDestination ! Message\fR\& after \fITime\fR\& milliseconds\&. (\fIDestination\fR\& can be a remote or local process identifier, an atom of a registered name or a tuple \fI{RegName, Node}\fR\& for a registered name at another node\&.) .RS 2 .LP Returns \fI{ok, TRef}\fR\& or \fI{error, Reason}\fR\&\&. .RE .RS 2 .LP See also the Timer Module section in the Efficiency Guide\&. .RE .TP 2 .B \fIsend_after/2\fR\&: Same as \fIsend_after(Time, self(), Message)\fR\&\&. .RE .RE .LP .nf .B send_interval(Time, Message) -> {ok, TRef} | {error, Reason} .br .fi .br .nf .B send_interval(Time, Destination, Message) -> .B {ok, TRef} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Time = time() .br Destination = .br pid() | .br (RegName :: atom()) | .br {RegName :: atom(), Node :: node()} .br Message = term() .br TRef = tref() .br Reason = term() .br .RE .RE .RS .RS 2 .TP 2 .B \fIsend_interval/3\fR\&: Evaluates \fIDestination ! Message\fR\& repeatedly after \fITime\fR\& milliseconds\&. (\fIDestination\fR\& can be a remote or local process identifier, an atom of a registered name or a tuple \fI{RegName, Node}\fR\& for a registered name at another node\&.) .RS 2 .LP Returns \fI{ok, TRef}\fR\& or \fI{error, Reason}\fR\&\&. .RE .TP 2 .B \fIsend_interval/2\fR\&: Same as \fIsend_interval(Time, self(), Message)\fR\&\&. .RE .RE .LP .nf .B sleep(Time) -> ok .br .fi .br .RS .LP Types: .RS 3 Time = timeout() .br .RE .RE .RS .LP Suspends the process calling this function for \fITime\fR\& milliseconds and then returns \fIok\fR\&, or suspends the process forever if \fITime\fR\& is the atom \fIinfinity\fR\&\&. Naturally, this function does \fInot\fR\& return immediately\&. .LP .RS -4 .B Note: .RE Before OTP 25, \fItimer:sleep/1\fR\& did not accept integer timeout values greater than \fI16#ffffffff\fR\&, that is, \fI2^32-1\fR\&\&. Since OTP 25, arbitrarily high integer values are accepted\&. .RE .LP .nf .B start() -> ok .br .fi .br .RS .LP Starts the timer server\&. Normally, the server does not need to be started explicitly\&. It is started dynamically if it is needed\&. This is useful during development, but in a target system the server is to be started explicitly\&. Use configuration parameters for Kernel for this\&. .RE .LP .nf .B tc(Fun) -> {Time, Value} .br .fi .br .nf .B tc(Fun, Arguments) -> {Time, Value} .br .fi .br .nf .B tc(Module, Function, Arguments) -> {Time, Value} .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Arguments = [term()] .br Time = integer() .br Value = term() .br .RE .RE .RS .RS 2 .TP 2 .B \fItc/3\fR\&: Calls function \fItimer:tc(Module, Function, Arguments, microsecond)\fR\&\&. .TP 2 .B \fItc/2\fR\&: Calls function \fItimer:tc(Fun, Arguments, microsecond)\fR\&\&. .TP 2 .B \fItc/1\fR\&: Calls function \fItimer:tc(Fun, microsecond)\fR\&\&. .RE .RE .LP .nf .B tc(Fun, TimeUnit) -> {Time, Value} .br .fi .br .nf .B tc(Fun, Arguments, TimeUnit) -> {Time, Value} .br .fi .br .nf .B tc(Module, Function, Arguments, TimeUnit) -> {Time, Value} .br .fi .br .RS .LP Types: .RS 3 Module = module() .br Function = atom() .br Arguments = [term()] .br TimeUnit = erlang:time_unit() .br Time = integer() .br .RS 2 In the specified \fITimeUnit\fR\& .RE Value = term() .br .RE .RE .RS .RS 2 .TP 2 .B \fItc/4\fR\&: Evaluates \fIapply(Module, Function, Arguments)\fR\& and measures the elapsed real time as reported by \fIerlang:monotonic_time/0\fR\&\&. .RS 2 .LP Returns \fI{Time, Value}\fR\&, where \fITime\fR\& is the elapsed real time in the specified \fITimeUnit\fR\&, and \fIValue\fR\& is what is returned from the apply\&. .RE .TP 2 .B \fItc/3\fR\&: Evaluates \fIapply(Fun, Arguments)\fR\&\&. Otherwise the same as \fItc/4\fR\&\&. .TP 2 .B \fItc/2\fR\&: Evaluates \fIFun()\fR\&\&. Otherwise the same as \fItc/3\fR\&\&. .RE .RE .SH "EXAMPLES" .LP \fIExample 1\fR\& .LP The following example shows how to print "Hello World!" in 5 seconds: .LP .nf 1> timer:apply_after(5000, io, format, ["~nHello World!~n", []])\&. {ok,TRef} Hello World! .fi .LP \fIExample 2\fR\& .LP The following example shows a process performing a certain action, and if this action is not completed within a certain limit, the process is killed: .LP .nf Pid = spawn(mod, fun, [foo, bar]), %% If pid is not finished in 10 seconds, kill him {ok, R} = timer:kill_after(timer:seconds(10), Pid), \&... %% We change our mind... timer:cancel(R), \&... .fi .SH "NOTES" .LP A timer can always be removed by calling \fIcancel/1\fR\&\&. .LP An interval timer, that is, a timer created by evaluating any of the functions \fIapply_interval/4\fR\&, \fIsend_interval/3\fR\&, and \fIsend_interval/2\fR\& is linked to the process to which the timer performs its task\&. .LP A one-shot timer, that is, a timer created by evaluating any of the functions \fIapply_after/4\fR\&, \fIsend_after/3\fR\&, \fIsend_after/2\fR\&, \fIexit_after/3\fR\&, \fIexit_after/2\fR\&, \fIkill_after/2\fR\&, and \fIkill_after/1\fR\& is not linked to any process\&. Hence, such a timer is removed only when it reaches its time-out, or if it is explicitly removed by a call to \fIcancel/1\fR\&\&.