gpt4 book ai didi

multithreading - Erlang 怎么 sleep (晚上?)

转载 作者:行者123 更新时间:2023-12-04 06:49:40 31 4
gpt4 key购买 nike

我想每隔几个小时在 Erlang 服务器上运行一个小型清理过程。

我知道计时器模块。我在教程中看到一个示例,使用链式计时器: sleep 命令来等待几天后发生的事件,我觉得这很奇怪。我知道 Erlang 进程与其他语言的进程相比是独一无二的,但是进程/线程一次休眠数天、数周甚至数月的想法似乎很奇怪。

因此,我着手找出 sleep 的实际作用的细节。我发现最接近的是一篇博客文章,其中提到 sleep 是通过接收超时实现的,但这仍然留下了问题:

这些 sleep /类似 sleep 的功能实际上是做什么的?

我的进程是否在休眠时占用资源?有数千个休眠进程会使用尽可能多的资源,例如,数千个进程服务于一个什么都不做的递归调用吗?在进程中反复休眠或长时间休眠是否会导致性能损失?虚拟机是否不断地消耗资源来查看结束进程 sleep 的条件是否成立?

作为旁注,如果有人可以评论是否有比 sleep 更好的方法来一次暂停数小时或数天,我将不胜感激?

最佳答案

这是任何 erlang 进程的业力:它等待或死亡 :o)

当一个进程被生成时,它开始执行直到最后一个执行行,然后死掉,返回最后一个评估。

为了使进程保持事件状态,没有其他解决方案可以在无休止的连续调用中递归循环。

当然,有几个条件使它停止或休眠:

  • 循环结束:进程收到一条消息,告诉他
    停止递归
  • 一个接收 block :该过程将等到一个消息
    匹配接收 block 中的一个条目将发布在消息中
    队列。
  • VM 调度程序暂时停止它以允许访问 CPU
    到其他进程

  • 在最后两种情况下,执行将在 VM 调度程序的责任下重新启动。

    在等待时它不使用 CPU 带宽,但保持与开始等待时完全相同的内存布局。 Erlang OTP 提供了一些方法来使用 hibernate 选项将这种内存布局减少到最低限度(请参阅 gen_serevr 或 gen_fsm 的文档,但我认为它仅供高级使用)。

    创建一个以常规(或几乎常规)间隔触发进程的“信号”的简单方法是有效地使用带有 timout 的接收 block (超时限制为 65535 毫秒),例如:
    on_tick_sec(Module,Function,Arglist,Period) -> 
    on_tick(Module,Function,Arglist,1000,Period,0).
    on_tick_mn(Module,Function,Arglist,Period) ->
    on_tick(Module,Function,Arglist,60000,Period,0).
    on_tick_hr(Module,Function,Arglist,Period) ->
    on_tick(Module,Function,Arglist,60000,Period*60,0).



    on_tick(Module,Function,Arglist,TimeBase,Period,Period) ->
    apply(Module,Function,Arglist),
    on_tick(Module,Function,Arglist,TimeBase,Period,0);
    on_tick(Module,Function,Arglist,TimeBase,Period,CountTimeBase) ->
    receive
    stop -> stopped
    after TimeBase ->
    on_tick(Module,Function,Arglist,TimeBase,Period,CountTimeBase+1)
    end.

    和用法:
    1> Pid = spawn(util,on_tick_sec,[io,format,["hello~n"],5]).
    <0.40.0>
    hello
    hello
    hello
    hello
    2> Pid ! stop.
    stop
    3>

    [编辑]

    timer 模块是一个标准的 gen_server,运行在一个单独的进程中。 timer 模块中的所有函数都是公共(public)接口(interface),它们执行隐藏的 gen_server:call 或 gen_server:cast 到 timer 服务器。这是隐藏服务器内部并允许进一步演进而不影响现有应用程序的常见用法。

    服务器在内部使用一个表(ets)来存储它必须执行的所有操作以及每个计时器引用,并且它使用自己的函数在需要时唤醒(最后,VM 必须处理这个?)。

    因此,您可以使进程休眠,而不会对计时器服务器行为产生任何影响。休眠机制是
  • 棘手,请参阅 hibernate/3 definition 上的文档,您将看到您必须自己“重建”上下文,因为所有内容都已从进程上下文中删除,并且系统存储了一个元组(模块,函数,参数},以便在需要时重新启动您的进程。
  • 垃圾收集和进程重启花费了一些时间

  • 这就是为什么我说它确实是一个需要充分理由使用的高级功能。

    关于multithreading - Erlang 怎么 sleep (晚上?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25054693/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com