簡體   English   中英

在流程之間進行多處理通信的最佳方式。

[英]Best way to communicate in multiprocessing between processes.

我正在嘗試編寫一個將作為一個單獨的進程運行的函數,並將在我告訴它在主進程上停止之前獲取數據。

下面是它的工作原理:

e = multiprocessing.Event()

def recordLeverPos(e, name): #e = multiprocessing.Event()
    posData = []
    while True:
        datBuffer = str(lever.readCounter()) + '\n'
        posData.append(datBuffer)
        if e.is_set() == True:
            with open('%s_leverPos.tsv' %(name), 'a') as file:
                for i in range(len(posData)):
                    posData[i] = posData[i]
                    file.write(posData[i])
            print 'Done Writing to leverPos file.'
            while e.is_set() == True:
                sleep(0.01)
            posData = []


p = mp.Process(target=recordLeverPos, args = (e, name))

def trialStart():
    global e

    #While trials is going on, some more code regarding the correct task that must be performed.
    e.set() #Indicate to the process that it's time to flush the buffer to the tsv file.


    #Depending on conditions, trial may continue to trial stop a function in which the patient must not do anything to the lever, but I still need to record the lever position.
    e.clear() #Indicate to process to get out of the while loop and start recording a new leverPos buffer.
    trialStop()

def trialStop():
    global e
    #Patient must not do anything here.... but if he/she does.
    if (lever.readCounter > threshold): #Patient  moved it.
        e.set() #Indicate to thread it's time to flush the buffer again.
        e.clear() #Indicate to thread you can start with a new buffer.

        #However the problem seems to be that when I call the e.set() in this function the process does not receive the event and does not save the Buffer... 

    #there's a timer here, if the timer passes I still want to record the position of the lever.

def main():
    p.start() #Begin adding leverPos to the buffer.
    trialStart()

因此,我調用該函數並將其放入一個與我的主函數分開運行的進程中。

p = mp.Process(target=recordLeverPos, args = (e, name))
p.start()

函數recordLeverPos通過將杠桿添加到列表緩沖區中來基本上記錄杠桿的位置,當試用結束時,我調用e.set() ,因此函數的下一部分被調用,這基本上是將列表緩沖區復制到一個tsv文件中。 然后該過程將一直等到我調用e.clear() 問題是:我似乎無法始終清除事件(值得注意的是,我創建了p和e全局變量,以便可以從運行某些試驗階段的其他函數訪問它們)。 每當我調用e.set()它似乎只對我調用e.set()的四個不同位置中的兩個e.set() 我的問題是,為什么會這樣? 有一種更好的方法可以以一種我可以稱之為全局的方式來做到這一點嗎?

有沒有更好的方式與流程進行溝通? 我嘗試進行自我搜索,但我不知道如何使用可選取的對象,老實說,事件函數/類對我來說似乎更直觀,但我似乎無法像我那樣使用它希望它能工作...

讓我知道是否需要更多代碼,我只是嘗試超級簡化我的代碼,以便您掌握主要思想,因此您不會浪費時間嘗試理解我的代碼的工作原理。

這是一些示例代碼,可讓數據滴入,然后在發出事件信號時將數據寫入文件。 它是獨立的,沒有依賴性。

注意事項:

  • 在使用is_set()檢查Event后,會立即將其清除。 這讓父進程再次set()

差不多了,原始代碼幾乎完成了!

資源

import multiprocessing, sys, time

record_ev = multiprocessing.Event()
name = 'beer'

def recordLeverPos(rec_ev, name): #e = multiprocessing.Event()
    posData = []
    lever = iter(xrange(999))
    while True:
        datBuffer = str(lever.next()) + '\n'
        posData.append(datBuffer)
        print 'posData',posData
        if rec_ev.is_set():
            rec_ev.clear()
            with open('%s_leverPos.tsv' % name, 'a') as dataf:
                for dat in posData:
                    dataf.write(dat)
            print 'wrote: {}'.format(posData)
            print 'Done Writing to leverPos file.'
            posData = []
        time.sleep(1)


record_proc = multiprocessing.Process(
    target=recordLeverPos, args = (record_ev, name)
)
record_proc.start()

time.sleep(2)
print 'triggering record'
record_ev.set()

time.sleep(2)
print 'triggering record #2'
record_ev.set()

time.sleep(2)
record_proc.terminate()
record_proc.join()
sys.exit(0)

產量

posData ['0\n']
posData ['0\n', '1\n']
triggering record
posData ['0\n', '1\n', '2\n']
wrote: ['0\n', '1\n', '2\n']
Done Writing to leverPos file.
posData ['3\n']
triggering record #2
posData ['3\n', '4\n']
wrote: ['3\n', '4\n']
Done Writing to leverPos file.
posData ['5\n']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM