2016-04-24 56 views
0

我正在開發一個項目,其中使用了大約6個傳感器喂入Beaglebone Black,它將數據保存到6個不同文件連續。通過另一個SO問題(https://stackoverflow.com/a/36634587/2615940),我瞭解到多處理模塊會爲我執行此操作,但是當運行我的新代碼時,我只獲得1個文件而不是6個。我如何修改此代碼以獲得所需的6個結果文件?使用python多重處理同時進行文件編寫

*根據skrrgwasme的建議,我編輯了我的文件以包含Manager,但現在代碼運行並不產生任何結果。沒有錯誤,沒有文件。就跑吧。

代碼:

import Queue 
import multiprocessing 
import time 

def emgacq(kill_queue, f_name, adcpin): 
    with open(f_name, '+') as f: 
     while True: 
      try: 
       val = kill_queue.get(block = False) 
       if val == STOP: 
        return 
      except Queue.Empty: 
       pass 
      an_val = ADC.read(adcpin) * 1.8 
      f.write("{}\t{}\n".format(ms, an_val)) 
def main():  
    #Timing stuff 
    start = time.time() 
    elapsed_seconds = time.time() - start 
    ms = elapsed_seconds * 1000 

    #Multiprcessing settings 
    pool = multiprocessing.Pool() 
    m = multiprocessing.Manager() 
    kill_queue = m.Queue()    

    #All the arguments we need run thru emgacq() 
    arg_list = [ 
     (kill_queue, 'HamLeft', 'AIN1'), 
     (kill_queue, 'HamRight', 'AIN2'), 
     (kill_queue, 'QuadLeft', 'AIN3'), 
     (kill_queue, 'QuadRight', 'AIN4'), 
     (kill_queue, 'GastLeft', 'AIN5'), 
     (kill_queue, 'GastRight', 'AIN6'), 
     ] 

    for a in arg_list: 
     pool.apply_async(emgacq, args=a) 

    try: 
     while True: 
      time.sleep(60) 
    except KeyboardInterrupt: 
     for a in arg_list: 
      kill_queue.put(STOP) 
     pool.close() 
     pool.join() 
     raise f.close() 

if __name__ == "__main__": 
    main() 
+0

鑑於你已經處理了這兩個問題的問題,我強烈建議你去通過一些基本的Python教程。似乎你對基本概念如函數調用,變量賦值和參數傳遞有一些困惑。如果您在深入瞭解下一個腳本/程序之前瞭解這些基礎知識,您將會獲得更多成功。 – skrrgwasme

回答

2

你的主要問題是,你對你的子進程函數的參數列表是不正確的:

f_list = [ 
    emgacq(kill_queue, 'HamLeft', 'AIN1'), 
    # this calls the emgacq function right here - blocking the rest of your 
    # script's execution 

此外,您apply_async電話是錯誤的:

for f in f_list: 
    pool.apply_async(f, args=(kill_queue)) 
    # f is not a function here - the arguments to the apply_async function 
    # should be the one function you want to call followed by a tuple of 
    # arguments that should be provided to it 

你想要這個,其中還包括一個manager EUE(見https://stackoverflow.com/a/9928191/2615940),並把所有的代碼在一個main功能:

# put your imports here 
# followed by the definition of the emgacq function 

def main(): 

    #Timing stuff 
    start = time.time() 
    elapsed_seconds = time.time() - start 
    ms = elapsed_seconds * 1000 

    pool = multiprocessing.Pool() 
    m = multiprocessing.Manager() 
    kill_queue = m.Queue() 

    arg_list = [ 
      (kill_queue, 'HamLeft', 'AIN1'), 
      (kill_queue, 'HamRight', 'AIN2'), 
      (kill_queue, 'QuadLeft', 'AIN3'), 
      (kill_queue, 'QuadRight', 'AIN4'), 
      (kill_queue, 'GastLeft', 'AIN5'), 
      (kill_queue, 'GastRight', 'AIN6'), 
     ] 

    for a in arg_list: 
     pool.apply_async(emgacq, args=a) 
     # this will call the emgacq function with the arguments provided in "a" 

if __name__ == "__main__": 
    # you want to have all of your code in a function, because the workers 
    # will start by importing the main module they are executing from, 
    # and you don't want them to execute that code all over again 
    main() 
+0

我無法理解這裏發生了什麼。看來現在有一個繼承問題。具體而言,「隊列對象只能通過繼承在進程之間共享」。 – boktor

+0

@boktor請參閱編輯。 – skrrgwasme

+0

我編輯的主要帖子,所以你可以看到當我嘗試'管理器。發生了什麼事情。我是否需要調整現在我使用'kill_queue'現在它的定義已經改變? ('kill_queue = m.Queue()'而不是'kill_queue = multiprocessing.Queue') – boktor

相關問題