Simultaneous write to multiple files

笑着哭i 提交于 2019-12-12 01:38:09

问题


I'm working on a project involving using a Beaglebone to read from multiple sensors and then pass that data into a text file.I'm monitoring six different muscles, so I have the files correspond to each.

Right now, there are 6 sensors feeding into the Beaglebone Black's ADC pins and my code instructs the Beaglebone to create 1 separate file for each pin. Whenever I run the below code, I only get the one file (the first function runs). Previously I had not included the "while True:" statements which resulted in 1-2 readings and six files created. I added the "while True:" to continuously record the sensors' data because that's what I thought was responsible for my not having more than 2 points in each file.

My question is: is it at all possible to write to multiple files at the same time? I could alternatively write all this data to the same file, but I'm interested in knowing what it is that makes this code not function as intended (6 files.)

        #File save for left hamstring
def LeftHamAcquisition():
        HamLData = open('HamLeft' + '.txt', 'a+')
        file_name = os.path.join(/relevant file path/)
        while True:
                EMGhamL = ADC.read_raw('AIN1')
                HamLData.write(str(elapsed_milliseconds))
                HamLData.write('\t')
                HamLData.write(str(EMGhamL))
                HamLData.write('\n')

        #File save for right hams
def RighHamAcquisition():
        HamRData = open('HamRight' + '.txt', 'a+')
        file_name2 = os.path.join(/relevant file path/)
        while True:
                EMGhamR = ADC.read_raw('AIN2')
                HamRData.write(str(elapsed_milliseconds))
                HamRData.write('\t')
                HamRData.write(str(EMGhamR))
                HamRData.write('\n')


        #file save for left quad
def LeftQuadAcquisition():        
        QuadLData = open('QuadLeft' + '.txt', 'a+')
        file_name3 = os.path.join(/relevant file path/)
        while True:
                EMGquadL = ADC.read_raw('AIN3')
                QuadLData.write(str(elapsed_milliseconds))
                QuadLData.write('\t')
                QuadLData.write(str(EMGquadL))
                QuadLData.write('\n')

        #file save for right quad
def RightQuadAcquisition():
        QuadRData = open('QuadRight' + '.txt', 'a+')
        file_name4 = os.path.join(/relevant file path/)
        while True:
                EMGquadR = ADC.read_raw('AIN4')
                QuadRData.write(str(elapsed_milliseconds))
                QuadRData.write('\t')
                QuadRData.write(str(EMGquadR))
                QuadRData.write('\n')

        #file save for left vast
def LeftVastAcquisition():
        VastLData = open('VastLeft' + '.txt', 'a+')
        file_name5 = os.path.join(/relevant file path/)
        while True:
                EMGVastL = ADC.read_raw('AIN5')
                VastLData.write(str(elapsed_milliseconds))
                VastLData.write('\t')
                VastLData.write(str(EMGVastL))
                VastLData.write('\n')

        #file save for right vast
def RightVastAcquisition():
        VastRData = open('VastRight' + '.txt', 'a+')
        file_name6 = os.path.join(/relevant file path/)
        while True:
                EMGVastR = ADC.read_raw('AIN6')
                VastRData.write(str(elapsed_milliseconds))
                VastRData.write('\t')
                VastRData.write(str(EMGVastR))
                VastRData.write('\n')

#The Program
print "Press ctrl-C to end acquisition"

LeftHamAcquisition()
RighHamAcquisition()
LeftVastAcquisition()
RightVastAcquisition()
LeftQuadAcquisition()
RightQuadAcquisition()

try:
    pass
except KeyboardInterrupt:      
    raise data.close()

回答1:


Your function calls have infinite loops in them, so they will never return. One file was created by LeftHamAcquisition, but since it never returned, none of the other functions were ever executed. You need to use something like the multiprocessing module to get them to run in parallel. In particular, I would recommend multiprocessing pools and the apply_async function:

import multiprocessing
import Queue
import time

# one global constant: the poison pill
# this could really be whatever you want - my string choice is arbitrary
STOP = "stop"

# change the signature of your function to accept a queue for the main 
# process to pass a poison pill
def LeftHamAcquisition(kill_queue):
    f_name = 'HamLeft.txt'

    # you aren't doing anything with "file_name" - should it be removed?
    # file_name = os.path.join(/relevant file path/)

    # use file context managers:
    with open(fname, 'a+') as HamLData:
        while True:

            # in the infinite loop, we add a check for the poison pill
            try:
                val = kill_queue.get(block=False)
                if val = STOP:
                    return # leave if the poison pill was sent
            except Queue.Empty:
                pass # ignore empty queue

            EMGhamL = ADC.read_raw('AIN1')
            HamLData.write(str(elapsed_milliseconds))
            HamLData.write('\t')
            HamLData.write(str(EMGhamL))
            HamLData.write('\n')

# ... the rest of your functions ...

#The Program
print "Press ctrl-C to end acquisition"

# a list of your functions
f_list = [
    LeftHamAcquisition,
    RighHamAcquisition,
    LeftVastAcquisition,
    RightVastAcquisition,
    LeftQuadAcquisition,
    RightQuadAcquisition,
]

pool = multiprocessing.Pool()    #c reate the worker pool
kill_queue = multiprocessing.Queue() # create the queue to pass poison pills

for f in f_list:
    # kick off the functions, passing them the poison pill queue
    pool.apply_async(f, args=(kill_queue))     
try:
    # put the main process to sleep while the workers do their thing
    while True:
        time.sleep(60)

except KeyboardInterrupt:      

    # close the workers nicely - put one poison pill on the queue for each
    for f in f_list:
        q.put(STOP)
    pool.close()
    pool.join()
    raise data.close()

Also, there's no reason to have this many functions. They all do the same thing, just with different strings and variable names. You should refactor them into one function that you can pass arguments to:

def acquisition(kill_queue, f_name, ain):

    with open(fname, 'a+') as f:
        while True:

            try:
                val = kill_queue.get(block=False)
                if val = STOP:
                    return
            except Queue.Empty:
                pass

            an_val = ADC.read_raw(ain)

            # where does "elapsed_milliseconds" come from? it's undefined
            # in your example code
            f.write("{}\t{}\n".format(elapsed_milliseconds, an_val))

With this function, instead of providing a list of individual functions in my multiprocessing example, you can just reuse this function call it repeatedly with different arguments (which is the whole point of functions).



来源:https://stackoverflow.com/questions/36634279/simultaneous-write-to-multiple-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!