发现阻止erlang线程

时间:2012-05-07 18:22:22

标签: erlang hotswap

我有一个包含许多模块的项目,每个模块都有不同的运行线程。我写了一个小脚本,遍历每个脚本并安全地重新加载代码(用于热交换):

reload_all() ->                
    ?MODULE:reload_all(?MODULE_LIST).
reload_all([]) -> ok;          
reload_all([T|C]) ->
    io:fwrite("Purging ~w\n",[T]),  
    try_purge(T),              
    {module,T} = code:load_file(T), 
    ?MODULE:reload_all(C).     

try_purge(T) -> try_purge(T,1).
try_purge(T,Wait) ->           
    case code:soft_purge(T) of 
    true -> ok;
    false ->
        io:fwrite("* Waiting ~w seconds for ~w module\n",[Wait,T]),
        timer:sleep(Wait*1000),
        try_purge(T,Wait+1)    
    end.

它使用soft_purge()函数,该函数仅在没有线程运行将被普通purge命令杀死的“旧”代码时清除代码。它将等待增加间隔并继续尝试。我设计了这个项目,以便等待的时间永远不会超过一分钟,但实际上它应该总是或多或少是即时的。

我遇到的问题是,有时一个模块会有一个错误导致它因某种原因无限期地阻塞,而我的reload_all()脚本永远不会完成。这是理想的行为,它让我知道出了什么问题。问题是,追踪错误涉及大量的测试和分析代码,有时甚至不起作用,因为错误只出现在生产环境而不是测试中。

我的问题是:有没有办法确定哪些线程在模块中运行“旧”代码,并查看它们当前卡在哪个函数中?

1 个答案:

答案 0 :(得分:1)

您可以使用erlang检查您是使用旧版本还是新版本:check_old_code / 1和erlang:check_process_code / 2。只需看Erlang manual