2012-05-07 40 views
1

我有有许多模块的项目,每个人都有不同的运行线程。我写了一个小脚本,经过每一个安全地重新加载代码(热插拔):发现阻塞线程二郎

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()函数,只有当有运行中的“旧”没有线程清除代码将被普通清除命令杀死的代码。它会不断增加等待时间并继续尝试。我已经设计了这个项目,以便等待时间永远不会超过一分钟,但实际上它应该总是或多或少是瞬间的。

我遇到的问题是,有时一个模块都会有一个bug导致它无限期地阻塞或那样的原因,我的reload_all()脚本永远不会完成。这是所需的行为,它让我知道有什么不对。问题是,追查错误涉及到很多很多的代码,有时甚至不工作,因为错误只在生产环境中显示出来,而不是在测试一个测试和分析的。

我的问题是:有没有一种方法,以确定哪些线程模块在运行的“老”的代码,看看他们目前被困在其中的功能?

+0

你是如何杀害其正在使用的模块的过程?这个功能只是等到他们死了? – rvirding

+0

我没有,soft_purge的观点是,没有线程永远不会死。如果有线程仍在使用旧代码,那么清除将不会发生。 –

回答

1

你可以,如果你使用的是旧的或使用该模块的新版本检查二郎:check_old_code/1和Erlang:check_process_code/2。请看Erlang manual

+0

check_process_code的作品,我可以做一个列表:过滤器(fun(Pid) - > erlang:check_process_code(Pid,?MODULE)end,erlang:processes())来获取仍然运行模块的旧代码的所有线程。谢谢! –