2016-04-14 27 views
0

Birden fazla sensörden okumak için bir Beaglebone kullanarak bir proje üzerinde çalışıyorum ve daha sonra bu verileri bir metin dosyasına geçiriyorum.İki farklı kasları izliyorum, bu yüzden her bir dosyaya karşılık gelen dosyalarım var .Birden çok dosya için eşzamanlı yazma

Şu anda Beaglebone Black'in ADC pinlerine beslenen 6 sensör bulunuyor ve kodum Beaglebone'a her pin için 1 ayrı dosya oluşturmasını bildiriyor. Aşağıdaki kodu çalıştırdığımda, sadece bir dosyayı (ilk işlev çalışır) alırım. Önceden "while True:" ifadelerini dahil etmemiştim, bu da 1-2 okuma ve altı dosya oluşturdu. Sensörlerin verilerini sürekli olarak kaydetmek için "while True:" ifadesini ekledim çünkü her dosyada 2'den fazla puan olmamasından sorumlu olduğumu düşündüm.

Sorum şu: Birden fazla dosyaya aynı anda yazmak mümkün mü? Ben alternatif aynı dosyaya tüm bu verileri yazabilirsiniz, ama bundan amaçlandığı şekilde bu kod çalışmaz hale getirir olup bittiğini bilmenin ilgileniyorum (6 dosyalar.)

 #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

Hepsinin işe yarayacağını düşündünüz? 'LeftHamAcquisition' sonsuz bir döngüye sahiptir, bu yüzden işlev asla geri dönmez. Çok işlemcili kütüphane gibi bir şeyi paralel olarak çalışacak şekilde gen kullanmanız gerekir. – skrrgwasme

+0

Diğer adam işaret ettiği gibi, her bir fonksiyon sonsuz bir döngü içerdiğinden, hiçbiri hiçbir zaman geri dönmeyecek, bu yüzden programınız ilk aranan her şeye yapışacaktır. Genelde pahalı bir işlem olduğu için, belleğe sürekli yazma genellikle en iyi seçenek değildir. Neden fonksiyonların her biri verileri arabelleğe göndermez, sonra ayrı bir iş parçacığına sahip olur. Her sensörü sırayla kontrol etmedikçe, yazıyı yapmak için neredeyse kesinlikle ayrı bir ipliğe ihtiyacınız olacaktır. – Carcigenicate

cevap

0

İşleviniz çağrıları onları sonsuz döngüye sahip Bu yüzden asla geri dönmeyecekler. Bir dosya LeftHamAcquisition tarafından oluşturuldu, ancak hiçbir zaman geri dönmediği için, diğer işlevlerin hiçbiri yürütülemedi. Paralel olarak çalışmalarını sağlamak için multiprocessing module gibi bir şey kullanmanız gerekir. Özellikle, multiprocessing pools ve apply_async fonksiyonu öneriyoruz:

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() 

Ayrıca, bu birçok işlev için hiçbir neden yok. Hepsi farklı dizeler ve değişken isimlerle aynı şeyi yaparlar. Sen argümanlar geçirebilmesi bir fonksiyonun içine yeniden düzenlemelisiniz: yerine benim çoklu işlem örnekte bireysel işlevlerin bir listesini sağlama, bu fonksiyon ile

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)) 

, sadece bu işlev farklı argümanlarla defalarca diyoruz yeniden kullanabilirsiniz (tüm fonksiyonlar noktası).

+0

Vay! Bu gerçekten temizlenmiş şeyleri. Muhtemelen, Python için yeni olduğumu tahmin ettiniz. Sonsuz döngüler hakkında bilgi sahibi oldum ama Beagle'ın kapıdan eş zamanlı olarak birden fazla döngü yapamayacağını bilmiyordum. * Bir sorum var, ikinci örneğinizde oluşturduğunuz genel işlevin argümanlarını nasıl girebilirdiniz? 'Kill_queue' basitçe" val "değerine eşit mi? – boktor

+0

@boktor Her iki sorunuz da [çok işlemcili dokümanlar] 'da (https://docs.python.org/2/library/multiprocessing.html) yanıtlanır. "Apply_async" ve "queue.get" bölümlerini okuyun ve hala anlamadıysanız tekrar buraya ping edin. – skrrgwasme

+0

Toplayabildiğim kadarıyla 'kill_queue', 'zehirli hap' ya da 'STOP' dizgisini girebilmeyi mümkün kılmak için standınız? – boktor

İlgili konular