erlang - erlang如何:now() work?

标签 erlang eshell

-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/3erlang: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/

相关文章:

erlang - 如何将字符串序列化的 Erlang 术语反序列化为 Java 中的 JInterface 对象?

process - Elixir进程,没有共享的堆内存

docker - 连接到 docker 容器中正在运行的 Erlang 应用程序版本

erlang - 检查邮箱是否为空?在二郎中

ubuntu - 如何安装 esl-erlang、erlang-crypto 和 erlang-tools?

bash - Emacs ido 风格的 shell

Emacs 外壳。如何在按 RET 时读取命令行的内容

shell - emacs中的shell和eshell有什么区别?

search - eshell 搜索历史

emacs - 在 emacs 的 eshell 中调用 su