-module(test_now).
-compile(export_all).
start() ->
{_, A, _} = now(),
loop(0, A).
loop(A) ->
{_, B, _} = now(),
if
B == A + 1 -> loop(0, B);
true -> loop(A)
end.
loop(T, B) ->
{_, C, _} = now(),
if
C == B + 1 -> io:write(T);
true -> loop(T+1, B)
end.
从逻辑上讲,这段代码应该运行 1+
秒。但是结果返回的很快,远不到一秒。如果我在 Eshell 中频繁调用test_now:start()
(向上箭头、输入、向上箭头、输入...),结果总是999999ok
.
最佳答案
来自文档(now/0):
It is also guaranteed that subsequent calls to this BIF returns continuously increasing values. Hence, the return value from now() can be used to generate unique time-stamps, and if it is called in a tight loop on a fast machine the time of the node can become skewed.
所以你不能使用now/0像你的例子一样检查时间。你可以试试os:timestamp/0相反:
start() ->
{_, S, MS} = os:timestamp(),
loop(0, {S, MS}).
loop(T, {S, MS}=Start) ->
{_, S2, MS2} = os:timestamp(),
if
S2 == S + 1 andalso MS2 == MS -> io:format("~p~n", [T]);
true -> loop(T + 1, Start)
end.
例子:
1> timer:tc(test_timestamp, start, []).
13600591
{1000047,ok}
但如果你只是想在一秒钟内得到一些通知,请考虑使用 erlang:send_after/3或 erlang:start_timer/3 :
start() ->
erlang:send_after(1000, self(), timeout),
loop(0).
loop(T) ->
receive
timeout -> io:format("~p~n", [T])
after
0 -> loop(T + 1)
end.
例子:
1> timer:tc(test_timer, start, []).
27433087
{1000520,ok}
关于erlang - erlang如何:now() work?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13549096/