Closed nschwanke closed 6 years ago
You can use this to stop / kill a thread (https://eli.thegreenplace.net/2011/12/27/python-threads-communication-and-stopping):
import os, time import threading, Queue
class WorkerThread(threading.Thread): """ A worker thread that takes directory names from a queue, finds all files in them recursively and reports the result.
Input is done by placing directory names (as strings) into the
Queue passed in dir_q.
Output is done by placing tuples into the Queue passed in result_q.
Each tuple is (thread name, dirname, [list of files]).
Ask the thread to stop by calling its join() method.
"""
def __init__(self, dir_q, result_q):
super(WorkerThread, self).__init__()
self.dir_q = dir_q
self.result_q = result_q
self.stoprequest = threading.Event()
def run(self):
# As long as we weren't asked to stop, try to take new tasks from the
# queue. The tasks are taken with a blocking 'get', so no CPU
# cycles are wasted while waiting.
# Also, 'get' is given a timeout, so stoprequest is always checked,
# even if there's nothing in the queue.
while not self.stoprequest.isSet():
try:
dirname = self.dir_q.get(True, 0.05)
filenames = list(self._files_in_dir(dirname))
self.result_q.put((self.name, dirname, filenames))
except Queue.Empty:
continue
def join(self, timeout=None):
self.stoprequest.set()
super(WorkerThread, self).join(timeout)
def _files_in_dir(self, dirname):
""" Given a directory name, yields the names of all files (not dirs)
contained in this directory and its sub-directories.
"""
for path, dirs, files in os.walk(dirname):
for file in files:
yield os.path.join(path, file)
Here's some simple code that uses this worker thread. It creates a thread pool with 4 threads, feeds them work and waits for all the results to arrive:
def main(args):
dir_q = Queue.Queue()
result_q = Queue.Queue()
# Create the "thread pool"
pool = [WorkerThread(dir_q=dir_q, result_q=result_q) for i in range(4)]
# Start all threads
for thread in pool:
thread.start()
# Give the workers some work to do
work_count = 0
for dir in args:
if os.path.exists(dir):
work_count += 1
dir_q.put(dir)
print 'Assigned %s dirs to workers' % work_count
# Now get all the results
while work_count > 0:
# Blocking 'get' from a Queue.
result = result_q.get()
print 'From thread %s: %s files found in dir %s' % (
result[0], len(result[2]), result[1])
work_count -= 1
# Ask threads to die and wait for them to do it
for thread in pool:
thread.join()
if name == 'main': import sys main(sys.argv[1:])
You can also do this as an another solution I think:
import subprocess import time
class LedDisplay(object): def init(self): self._proc = subprocess.Popen(["/home/pi/display16x32/rpi-rgb-led-matrix/text-example", "-r", "16", "-f", "/home/pi/4x6.bdf"], stdin=subprocess.PIPE)
def clear(self):
self._proc.stdin.write('\n')
def display(self, line1, line2=None):
self._proc.stdin.write('%s\n' % line1)
if line2:
self._proc.stdin.write('%s\n' % line2)
def stop(self):
self._proc.communicate()
disp = LedDisplay()
def main(): while True: game_info = ['portuguese', 1] disp.display('Team: %s' % game_info[0], 'Score: %s' % game_info[1]) time.sleep(5)
if name == "main": main()
self._proc = subprocess.Popen(["/home/pi/display16x32/rpi-rgb-led-matrix/text-example", "-r", "16", "-f", "/home/pi/display16x32/rpi-rgb-led-matrix/fonts/4x6.bdf"], stdin=subprocess.PIPE)
Thanks for your responses! I decided to go a different route and do the scripting completely in python and utilize the matrix.Clear() function at the end of loops running the animations.
Yes you can do that if the animation is static and use the method Clear() in the matrix (matrix.Clear()). But if the animation has a scroll during a time or a number of times I think this solution will not work, and you need to use threads, for when you ask for a method to show in the matrix to kill all the threads that are running and do the new thread.
Yes, doing things programmatically directly in Python this is the right approach @nschwanke Killing and restarting the process would just ask for trouble.
Dear Henner I have a draw number function and a scroll text fuction and between them I use threads to not have sobrepose the pixels and also matrix.Clear() function.
I am attempting to display different animations in a Python script on my led matrix by accessing the image-viewer utility via the subprocesses.Popen command. This works successfully, however when I want to switch to a new one the matrix is overwritten instead of cleared and replaced. I have attempted to catch the pid with a variable p and use p.kill() or p.terminate() to end the utility subprocces before beginning again but this does not work.
Is what I am trying to do possible? Or do I really need to write my own image-viewer in python to get the type of state machine driven animations wanted?