我有这两个功能
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).
主要思想是我计划每个请求到期时应该执行的时间。到期后,我想与其他可能及时到期的请求同时执行请求,因此我使用新进程生成请求函数。现在,如果我有数百万的请求,我将有数百万个进程,我认为这是不可取的。请求执行可能持续最多一分钟。 我想知道当我生成的函数完成时该过程会发生什么。它被杀了吗?或者它是否仍然存在并且应该被垃圾收集?我真的需要并发请求,不知道我怎么能实现它。 还有一些OTP行为在这种情况下可能会有所帮助吗?我还没有研究过OTP,我在整个Erlang框架的中间位置。
答案 0 :(得分:2)
当函数完成运行时,生成的进程退出。没有什么需要垃圾收集;整个进程堆被释放。 (除了超过64字节的二进制文件,它们保存在共享堆中。)
关于您的代码的说明:如果您需要将长列表分成满足某个谓词的元素和不需要的元素,那么使用lists:partition/2比使用{{3}}更有效lists:filter
然后--
。前者以线性时间运行到列表的长度,而如果您不幸,--
可以在二次时间内运行。
答案 1 :(得分:2)
您的任务完全是&#34;最大堆/优先级队列&#34;模板。它应该解决不是过滤列表,而是弹出具有最高优先级的元素(到期时间越近,给定时刻越高,优先级越高) 在优先级队列中提取元素将花费O(1)时间。 如果所有进程同时到期,您将需要遍历所有队列。
此外,我会将此队列拆分为大量优先级队列(如果可能,则独立),并同时处理它们。
在Erlang中,你真的可以监控其他进程(观察他们的&#34;退出&#34;代码)。此外,这可以使用OTP主管来完成。
答案 2 :(得分:1)
考虑到这里最糟糕的情况(根据我对您的问题/要求的理解),在同一时间到期的一百万个请求中,除了通过以下方式处理它们之外,您没有太多选择:
1.将过程限制从默认的32k增加到更合理的值。 (取决于您的资源可用性和测试结果)并一次处理过期结果(32k - 一些偏移)(默认情况)。
2.如果您可以选择跨多个节点(在同一台机器/不同的机器上)分发流程,则可以进一步处理上述方法。但同一台机器上的多个节点也将取决于您的资源可用性。
在erlang中,一旦由生成的进程执行的函数退出,进程本身就会退出。