2014-10-30 2 views
0

Ищете помощь, чтобы этот код работал (лучше)? Программа зависает после того, как цикл работает некоторое время (15-20 минут). Мне сказали несколько пользователей, что синхронизация с использованием time.sleep() не очень хорошая идея, и мне интересно, если это моя проблема. Пожалуйста, используйте мой код в качестве примера, когда вы отвечаете, потому что я новичок, когда дело доходит до Python. Чем проще, тем лучше.Резьбовая петля после 20 минут (RPi/GPIO)

Код должен воспроизводить цикл видео по умолчанию, а при нажатии кнопки (RPi/GPIO) воспроизводится другое видео. Как только это видео будет завершено, оно вернется к зацикленному видео по умолчанию. Я использую OMXPlayer, как вы можете видеть.

#!/usr/bin/python 

from time import sleep 
import RPi.GPIO as GPIO 
import subprocess 
import time 
import thread 

GPIO.setmode (GPIO.BCM) 
GPIO.setwarnings (False) 

GPIO.setup(4, GPIO.IN) # Button 1 
GPIO.setup(9, GPIO.IN) # Button 2 
GPIO.setup(10, GPIO.IN) # Button 3 
GPIO.setup(11, GPIO.IN) # Button 4 
GPIO.setup(17, GPIO.IN) # Button 5 
GPIO.setup(22, GPIO.IN) # Button 6 
GPIO.setup(27, GPIO.IN) # Button 7 

video_playing = False # Loop flag initial status 

def welcome_loop(): 
    global playProcess 
    while True: 
     x = 1 
     if not video_playing: 
       print "Play Welcome Video" 
       time.sleep(.05) 
       playProcess=subprocess.Popen(['omxplayer','-b','Desktop/videos/loop/loop.mp4'], 
               stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
               stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(24) # Length of video 
     x += 1 

def videos(): 
    #initialise a previous input variable to 0 (assume button not pressed last) 
    prev_input = 0 
    global video_playing 
    while True: 
     button1 = GPIO.input(27) 
     if ((not prev_input) and button1): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video  
       time.sleep(.5) 
       print "Play Martin Lab - Reel" 
       martinlab_reel=subprocess.Popen(['omxplayer','-b','Desktop/videos/martinlab_reel.mp4'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(30) # Length of video 
       martinlab_reel.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button1 
     #slight pause to debounce 
     time.sleep(.25) 

     button2 = GPIO.input(9) 
     if ((not prev_input) and button2): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video 
       time.sleep(.5) 
       print "Play Shoppingcart" 
       shoppingcart=subprocess.Popen(['omxplayer','-b','Desktop/videos/shoppingcart.mp4'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(111) # Length of video 
       shoppingcart.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button2 
     #slight pause to debounce 
     time.sleep(.25) 

     button3 = GPIO.input(10) 
     if ((not prev_input) and button3): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video 
       time.sleep(.5) 
       print "Play Dodgeballs" 
       dodgeballs=subprocess.Popen(['omxplayer','-b','Desktop/videos/dodgeballs.mp4'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(102) # Length of video 
       dodgeballs.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button3 
     #slight pause to debounce 
     time.sleep(.25) 

     button4 = GPIO.input(11) 
     if ((not prev_input) and button4): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video 
       time.sleep(.5) 
       print "Play Hidden Camera" 
       hiddencamera=subprocess.Popen(['omxplayer','-b','Desktop/videos/hiddencamera.mov'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(37) # Length of video 
       hiddencamera.stdin.write('q') # Stop video 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button4 
     #slight pause to debounce 
     time.sleep(.25) 

     button5 = GPIO.input(17) 
     if ((not prev_input) and button5): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video  
       time.sleep(.5) 
       print "Play Light of Human Kindness" 
       lohk_reel=subprocess.Popen(['omxplayer','-b','Desktop/videos/LOHK_short.mp4'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(83) # Length of video 
       lohk_reel.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button5 
     #slight pause to debounce 
     time.sleep(.25) 

     button6 = GPIO.input(22) 
     if ((not prev_input) and button6): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video  
       time.sleep(.5) 
       print "Play RVA Makerfest" 
       rva_makerfest=subprocess.Popen(['omxplayer','-b','Desktop/videos/rva_makerfest.mp4'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(101) # Length of video 
       rva_makerfest.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button6 
     #slight pause to debounce 
     time.sleep(.25) 

     button7 = GPIO.input(27) 
     if ((not prev_input) and button7): 
       video_playing = True # Set the flag (loop pauses) 
       print "Stop Welcome Video" 
       time.sleep(.5) 
       playProcess.stdin.write('q') # Stop video  
       time.sleep(.5) 
       print "Play PartyBot - Reel" 
       partybot_reel=subprocess.Popen(['omxplayer','-b','Desktop/videos/partybot_reel.mov'], 
                stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,close_fds=True) 
       time.sleep(61) # Length of video 
       partybot_reel.stdin.write('q') 
       video_playing = False # Unset the flag (loop continues) 

     #update previous input 
     prev_input = button7 
     #slight pause to debounce 
     time.sleep(.25) 

thread.start_new_thread(videos,()) # Videos thread 
thread.start_new_thread(welcome_loop,()) # Loop thread 

while True: 
    pass 

GPIO.cleanup() #Reset GPIOs 

ОШИБКА (После 2-часового пробега):

Unhandled exception in thread started by <function welcome_loop at 0xb6c8b3b0> 
Traceback (most recent call last): 
    File "./labmural2.py", line 32, in welcome_loop 
    stderr=subprocess.PIPE,close_fds=True) 
    File "/usr/lib/python2.7/subprocess.py", line 679, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.7/subprocess.py", line 1153, in _execute_child 
    self.pid = os.fork() 
OSError: [Errno 12] Cannot allocate memory 

бесформенный Возвращаемые значения (Память Useage):

Partition of a set of 26904 objects. Total size = 1957148 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 12601 47 786404 40 786404 40 str 
    1 6274 23 254548 13 1040952 53 tuple 
    2 1756 7 126432 6 1167384 60 types.CodeType 
    3  80 0 122944 6 1290328 66 dict of module 
    4 203 1 108292 6 1398620 71 dict of type 
    5 1709 6 102540 5 1501160 77 function 
    6 121 0 98540 5 1599700 82 dict (no owner) 
    7 203 1 90232 5 1689932 86 type 
    8 121 0 70316 4 1760248 90 dict of class 
    9 1054 4 42160 2 1802408 92 __builtin__.wrapper_descriptor 

бесплатно -m:

   total  used  free  shared buffers  cached 
Mem:   247  159   87   0   7   75 
-/+ buffers/cache:   76  170 
Swap:   99   8   91 
+0

Это * сбой * (есть ли трассировка?) Или программа висит? Если это последний, попробовали ли вы добавить код отладки (например, 'print'), чтобы выяснить, где именно его замораживание? – dano

+0

Это просто висит. Когда цикл видео возобновляется, экран становится черным. Нет ошибок. Это хорошая идея. Я попробую. Потому что мне трудно понять предложение о потоке/очереди. Но не сдаваться! – jmcclaire

+0

Я удалил переменную -b из команды запуска omxplayer, которая создает черный фон позади видео, и до сих пор он отлично справляется. Я просто должен добавить черное полотно с pygame или что-то, если это сработает. Надеюсь, мы дома бесплатно!Я дам Вам знать. – jmcclaire

ответ

0

Используйте потоки и очередь вместо потоков и глобальных переменных.

+0

Мне нужно посмотреть, как это сделать. Спасибо за ответ. – jmcclaire

0

Возможно, у вас закончились нехватка памяти или доступных процессов из-за того, что вы запускаете процессы и ожидаете их завершения. После того, как ваша программа работает некоторое время, используйте ps -AF, чтобы проверить количество запущенных процессов.

Представьте, что видео, которое вы пытаетесь воспроизвести, запускается в течение 9 секунд вместо 10 секунд. Это приведет к тому, что система попытается снова запустить воспроизведение видео до того, как первый из них завершится из-за вызовов time.sleep(). В конце концов вы получаете много перекрывающихся видеоплееров, пытающихся запустить одно и то же видео и так выхлопную память или количество процессов, разрешенных операционной системой.

Я предлагаю, чтобы изменить игру/ждать конструкций на что-то вроде этого:

playProcess=subprocess.Popen(['omxplayer','-b','Desktop/videos/loop/loop.mp4'], 
               stdin=subprocess.PIPE,stdout=subprocess.PIPE, 
               stderr=subprocess.PIPE,close_fds=True) 
playProcess.wait() # Wait for video to finish playing 
+0

Спасибо @Austin Phillips. Кажется, он уже работает. Используя 'free -m', похоже, что я не теряю память. Я отпущу его на некоторое время и дам вам знать, что произойдет. Скрещенные пальцы! – jmcclaire

+0

После 10 минут работы видео перестает играть и просто зависает. Нет ошибок или трассировки. Данг, я думал, что у нас это есть. Что делать, если я использую 'time.sleep()' до тех пор, пока видео не закончится? – jmcclaire

+0

Нет. Это не работает, использование 'time.sleep()' создает несколько процессов. Может быть, есть способ заставить 'playProcess.wait()' работать ... hmmm – jmcclaire

0

я имею эту проблему и, когда проверка открытия файла в Linux я понимаю увеличить количество файлов в зависимости от времени. поэтому после того, как число файлов достигнет остановки «ulimit -n», остановитесь. Мое решение было увеличение числа открытых файлов в Linux, и я увеличить количество файлов до 1000000. путем использования ссылке ниже:

https://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/

, но в основном это решение не допустить, чтобы открыть много файлов. (я просто использую класс для чтения температуры с помощью, и я не знаю, почему увеличение количества файлов в соответствии с временем)

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/17439850) –

+0

Как кто-то знаком с Linux, описание кажется адекватным. Вероятно, это неправильный ответ, поскольку, вероятно, есть утечка, но это причина для голосования без флага –

Смежные вопросы