Concurrency 如何更有效地在Erlang中生成进程?

Concurrency 如何更有效地在Erlang中生成进程?,concurrency,erlang,spawn,otp,Concurrency,Erlang,Spawn,Otp,我有这两个功能 check_requests(Timestamp,Plan,AddInfo)-> {Day,_Month,_Year,Hour,Minute,Second,Micro} = Timestamp, ExpiredRequests = lists:filter(fun(Elem) -> {_ID,Time,_Key,_Action} = Elem,

我有这两个功能

check_requests(Timestamp,Plan,AddInfo)->
    {Day,_Month,_Year,Hour,Minute,Second,Micro} = Timestamp,
    ExpiredRequests = lists:filter(fun(Elem) -> 
                               {_ID,Time,_Key,_Action} = Elem,
                               Time < {Day,Hour,Minute,Second,Micro}
                               end, Plan),
    NewPlan = Plan -- ExpiredRequests,
    make_requests(ExpiredRequests,AddInfo),
    NewPlan.

make_requests([],_)->ok;
make_requests([ExpiredRequest|Rest],AddInf)->
    {_ID,_Time,Key,Action} = ExpiredRequest,
    spawn(?MODULE,request,[AddInf,Action,Key]),
    make_requests(Rest,AddInf).
检查请求(时间戳、计划、附加信息)->
{Day,_Month,_Year,Hour,Minute,Second,Micro}=时间戳,
ExpiredRequests=列表:过滤器(乐趣(元素)->
{{u ID,Time,{u Key,{u Action}=Elem,
时间<{日、时、分、秒、微}
结束,计划),
NewPlan=Plan--ExpiredRequests,
提出请求(过期请求、附加信息),
新计划。
发出请求([],)->ok;
发出请求([ExpiredRequest | Rest],AddInf)->
{{u ID,{u Time,Key,Action}=ExpiredRequest,
生成(?模块,请求,[AddInf,操作,键],
提出请求(Rest、AddInf)。

主要的想法是,我有一个计划,每个请求都有一个到期的时间,应该执行。到期后,我希望与其他可能到期的请求同时执行该请求,因此我使用新进程生成请求函数。现在,如果我有数以百万计的请求,我将有数以百万计的进程,我认为这是不可取的。请求执行最长可能持续一分钟我想知道当我生成的函数完成时,进程会发生什么情况。它被杀死了吗?还是它仍然存在并且应该被垃圾收集?我真的需要并发的请求,不知道我还能如何实现它<也有一些OTP行为在这种情况下会有帮助吗?< /强>我还没有研究过OTP,我在整个Erlang框架的某个地方。

< p>当函数完成运行时生成的进程退出。没有什么东西需要垃圾收集;整个进程堆被释放。(超过64字节的二进制文件除外,它们保存在共享堆中。)


关于代码的注意事项:如果需要将一个长列表分为满足某个谓词的元素和不满足该谓词的元素,那么使用它比使用
列表:筛选
,然后再使用
--
更有效。前者以列表长度的线性时间运行,而
--
如果您运气不好,则可以以二次时间运行。

当函数完成运行时,生成的进程将退出。没有什么东西需要垃圾收集;整个进程堆被释放。(超过64字节的二进制文件除外,它们保存在共享堆中。)


关于代码的注意事项:如果需要将一个长列表分为满足某个谓词的元素和不满足该谓词的元素,那么使用它比使用
列表:筛选
,然后再使用
--
更有效。前者以列表长度的线性时间运行,而
--
如果您运气不好,则可以以二次时间运行。

考虑到最坏的情况(根据我从您的问题/需求中了解的情况),一百万个请求同时过期,除了通过以下方式成批处理它们之外,您没有太多选择:
1.将进程限制从默认值32k增加到更合理的值。(取决于您的资源可用性和测试结果)并一次处理过期结果(32k-某些偏移量)(默认情况)
2.如果您可以选择跨多个节点(在同一台机器/不同的机器上)分发流程,则可以进一步使用上述方法。但同样,同一台机器上的多个节点将取决于您的资源可用性。


在erlang中,一旦生成的进程执行的函数退出,进程本身也会退出。

考虑到这里最坏的情况(根据我从您的问题/需求中了解到的情况),一百万个请求同时过期,除了通过以下方式批处理它们之外,您别无选择:
1.将进程限制从默认值32k增加到更合理的值。(取决于您的资源可用性和测试结果)并一次处理过期结果(32k-某些偏移量)(默认情况)
2.如果您可以选择跨多个节点(在同一台机器/不同的机器上)分发流程,则可以进一步使用上述方法。但同样,同一台机器上的多个节点将取决于您的资源可用性。

在erlang中,一旦派生进程执行的函数退出,进程本身也会退出。

您的任务完全是一个“最大堆/优先级队列”模板。它不应该作为筛选列表来解决,而应该作为弹出具有最高优先级的元素来解决(截止日期越接近给定时刻,优先级越高) 在优先级队列中,提取元素需要O(1)个时间。 只有当所有进程同时过期时,才需要遍历所有队列

另外,我会将这个队列分成大量优先级队列(如果可能的话,是独立的),并同时处理它们

在Erlang中,您确实可以监视其他进程(查看它们的“退出”代码)。此外,这可以使用OTP管理器来完成。

您的任务完全是一个“最大堆/优先级队列”模板。它不应该作为筛选列表来解决,而应该作为弹出具有最高优先级的元素来解决(截止日期越接近给定时刻,优先级越高) 在优先级队列中,提取元素需要O(1)个时间。 只有当所有进程同时过期时,才需要遍历所有队列

另外,我会将这个队列分成大量优先级队列(如果可能的话,是独立的),并同时处理它们

在Erlang中,您确实可以监视其他进程(查看它们的“退出”代码)。此外,这可以通过OTP监督员来完成