用多个线程多次调用一个方法 [英] Calling a Method several times with several Threads
问题描述
我希望LED闪烁,同时正在对Raspberry进行一些工作.我在Python脚本中为LED使用了线程.
I want a LED to flash, while some work is beeing done on my Raspberry. I am using a Thread for the LED in my Python script.
初始代码:
import RPi.GPIO
import time
import threading
pinLED = 10
pinButton = 12
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pinLED, GPIO.OUT)
GPIO.setup(pinButton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.output(pinLED, 0)
线程的方法:
working = False
def flash():
status = 0
while working:
time.sleep(0.5)
if status == 0:
GPIO.output(pinLED, 1)
status = 1
else:
GPIO.output(pinLED, 0)
status = 0|
GPIO.output(pinLED, 0)
逻辑:
try:
while True:
time.sleep(0.02) #found out that 0.02 is a good value to get every tiny button push and save resources
if GPIO.input(pinButton) == 1:
t = threading.Thread(target=flash)
working = True
t.start()
time.sleep(5) #work would be here
working = False
t.join()
except Exception as e:
print(e)
finally:
GPIO.cleanup()
当我启动脚本并第一次按下按钮时,一切正常,并且LED闪烁.但是,当我第二次按下按钮而没有重新启动脚本时,LED指示灯没有闪烁.我打印了一些调试消息,发现t.start()被调用了,但是由于某种原因它什么也不做,也没有抛出异常.每次我再次按该按钮时,LED不应开始闪烁吗?
When I start the script and press the button the first time, everything is working and the led is flashing. But when i press the button a second time, without restarting the script, the led isn't flashing. I printed some debug messages and found out, that t.start() is called, but for some reason it's doing nothing, also no Exception is thrown. Shouln't the LED start flashing every time I press the button again?
推荐答案
我没有发现 logic 错误,并且我确认它是可行的,但是使用了以下更改:
I found no logic fault and i confirm it works, but used the following changes:
- 从
if __name__ == '__main__':
内部启动main_thread
.
我建议也将所有GPIO
调用移到该block
内部.
- Starting the
main_thread
from insideif __name__ == '__main__':
.
I suggest to move also allGPIO
calls inside thisblock
.
避免放置在if __name__ == '__main__':
从文档中: 安全导入主模块 应该使用if __name__ =='__main__'来保护程序的入口点":
From the docs: Safe importing of main module One should protect the "entry point" of the program by using if __name__ == '__main__':
-
在
working = False
之后添加了join()
,这确保线程在重新启动之前已终止.
Added
join()
afterworking = False
, this guaranteed the thread has terminated befor starting it again.
working = False
t.join()
我建议将def flash()
更改为以下内容:
使用threading.Event()
代替global Instance
,并将其与pinLED
一起传递.
这样可以概括def flash(...)
并允许将其与不同的pinLED
甚至并行使用.
将status
定义为threading.local()
线程安全,因此对于单独的线程,实例的值将有所不同.
例如:
I would suggest to change the def flash()
, to the following:
Using threading.Event()
instead of a global Instance
and passing it together with the pinLED
.
This generalizes the def flash(...)
and allow its use with different pinLED
, even parallel.
Define status
as threading.local()
threadsafe, so instance’s values will be different for separate threads.
For instance:
def flash(pinLED, flashing):
status = threading.local()
status.LED = False
while flashing.is_set():
status.LED = not status.LED
GPIO.output(pinLED, int(status.LED))
time.sleep(0.5)
GPIO.output(pinLED, 0)
更改为main_thread
:
def main_thread():
flashing = threading.Event()
flashing.clear()
try:
while True:
time.sleep(0.02)
if GPIO.input(pinButton) == 1:
t = threading.Thread(target=flash, args=(pinLED, flashing,))
flashing.set()
t.start()
time.sleep(2) # work would be here
flashing.clear()
t.join()
...
使用Python:3.4.2
Tested with Python:3.4.2
这篇关于用多个线程多次调用一个方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!