2012-05-07 41 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())來獲取仍然運行模塊的舊代碼的所有線程。謝謝! –