2014-01-15 98 views
0

我知道有關於這個話題不少其他的問題,我已經讀/與解決方案的嘗試,但沒有人相當做我想做或不工作......多處理和matlibplot,無阻塞地塊

什麼即時試圖做的事:

我想使用matplotlib,在一個新的進程,使得它在主線程運行時,主線程退出另外,當打開且響應推出了陰謀建立一個陰謀不要殺死子進程。如果可能的話,我想要一些可移植的東西,因此我已經避免了叉子,因爲我的印象是它不是(正確的)。我已經在matplotlib中嘗試了這個節目(block = False)。如果沒有什麼我很樂意接受,但最好是主線程退出,並且地塊仍然坐在那裏。

我迄今爲止最好的嘗試:

此代碼是從Python close children when closing main process

import logging, signal, sys, time 
import multiprocessing as mp 
import matplotlib.pyplot as plt 
from mpl_toolkits.axes_grid.axislines import SubplotZero 

class AddProcessNameFilter(logging.Filter): 
    """Add missing on Python 2.4 `record.processName` attribute.""" 
    def filter(self, r): 
     r.processName = getattr(r, 'processName', mp.current_process().name) 
     return logging.Filter.filter(self, r) 

def print_dot(plt): 
    signal.signal(signal.SIGTERM, signal.SIG_IGN) 
    while True: 
     mp.get_logger().info(".") 
     plt.show(block=True) 

def main(): 
    logger = mp.log_to_stderr() 
    logger.setLevel(logging.INFO) 
    logger.addFilter(AddProcessNameFilter()) # fix logging records 

    fig = plt.figure() 
    ax = fig.add_subplot(111) 
    ax.plot([0, 1, 2, 3], [1, 1, 3, 2],'ro') 

    # create daemonic child processes 
    p = mp.Process(target=print_dot, args=(plt,)) 
    p.daemon = True 
    p.start()  

if __name__=="__main__": 
    mp.freeze_support() 
    main() 

恰好這個代碼是什麼修改...

該地塊還沒有推出主線程不會退出它只是等待加入。當被打斷時,我也得到以下錯誤...

X Error of failed request: BadIDChoice (invalid resource ID chosen for this connection) 
    Major opcode of failed request: 53 (X_CreatePixmap) 
    Resource id in failed request: 0x4400017 
    Serial number of failed request: 344 
    Current serial number in output stream: 352 

不知道該怎麼做。有任何想法嗎? 在此先感謝:d

PS:Ubuntu的12.04 ...但我不知道如果多數民衆贊成在這種情況下,尤其重要...

+0

以相反的方式做出來,在主線程上保留陰謀,在另一個進程中進行計算。而且你還應該考慮將matplotlib嵌入到其中一個工具包(它已經爲你完成了很多可移植性問題)並且具有適當的線程支持。 – tacaswell

+0

嗯...這可能是一個選項,但我需要等待數據與p.join()?這些情節會不會對他們做出反應? (即保存等)。生病看看工具包:D –

+0

使用'multiprocess' +'signals'中的隊列來間隔輪詢它們。 – tacaswell

回答

0

我使用下面的代碼。它和你的類似,但加入了舊的過程,因爲函數應該被調用很多次。您可以關閉主流程,劇情不會關閉。

不能保證在p.start被調用之後,圖表會立即顯示。但這是非常不尋常的,發生在我身上的幾次。在這些時候,如果再次調用繪圖或者如果我調用p.is_alive(),則顯示窗口。

import multiprocessing as mp 
    import sys 
    def foo(*arg): 
     import matplotlib.pyplot as plt 
     plt.ioff()  
     plt.plot(*arg) 
     plt.show() 

    if __name__ == '__main__': 
     mp.freeze_support() 
     arg=(range(10),) 
     global pl 

     #create the process list, if it does not exists 
     try: 
      pl 
     except NameError: 
      pl = []  

     #Join old ones to keep zombie process list small 
     for i in range(len(pl)): 
      if not (pl[i] is None): 
       if not pl[i].is_alive(): 
        pl.pop(i).join() 


     #create plot process 
     p = mp.Process(target=foo, args=arg) 
     p.start() 
     pl.append(p)