问题
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