【问题标题】:Python Parallelism with GPIO and MultiprocessingPython 并行与 GPIO 和多处理
【发布时间】:2018-01-24 13:07:02
【问题描述】:

我的程序的目标是让两个复选框开始独立但并行的 while 循环。我考虑过线程,但 GIL 不应该阻止它工作吗?这些循环需要彼此完全独立。此外,用户界面锁定。循环中的.sleep 越长,锁定的时间就越长。我认为这可能是问题所在,因为如果他们同时更新top,它可能会阻止它工作,但是如果没有那些top.update,当我启动其中一个循环时,代码将完全停止工作。如何实现我正在寻找的并行性?

import multiprocessing
from multiprocessing import Process
GPIO.setmode(GPIO.BCM)
pinlist = [18, 23]

for i in pinlist:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.HIGH)

def CButtoncmd1():
    while(ActivateVar1.get()):
        GPIO.output(18, GPIO.LOW)
        top.update()
        time.sleep(.5);
        GPIO.output(18, GPIO.HIGH)
        top.update()
        time.sleep(.5);

def CButtoncmd2():
    while(ActivateVar2.get()):
        GPIO.output(23, GPIO.LOW)
        top.update()
        time.sleep(.5);
        GPIO.output(23, GPIO.HIGH)
        top.update()
        time.sleep(.5);

top = tkinter.Tk()

ActivateVar1 = DoubleVar()
CButtonActivate1 = CheckButton(top, text="start1", variable=ActivateVar1, command=CButtoncmd1)
CButtonActivate1.pack()

ActivateVar2 =DoubleVar()
CButtonActivate2 = CheckButton(top, text="start2", variable=ActivateVar2, command=CButtoncmd2)
CButtonActivate2.pack()

top.mainloop()

Light1 = multithreading.Process(target=CButtoncmd1, name="Light1")
Light2 = multithreading.Process(target=CButtoncmd1, name="Light2")
Light1.start()
Light2.start()

【问题讨论】:

    标签: python multithreading parallel-processing python-multithreading


    【解决方案1】:

    Tkinter 已经实现了自己的处理循环。您只需要使用现有的 TK 变量(或通过命令回调设置其他变量)来告诉线程您处于什么状态。然后可以通过线程完成 GPIO 更新。看看下面的例子..

    import time
    import Tkinter as tkinter
    import threading
    
    def lightControl(lnum, blink_var):
        global run
        while run:
            if blink_var.get():   # blink
                print lnum, ' on'
                time.sleep(0.5)
                print lnum, ' off'
                time.sleep(0.5)
            else:
                time.sleep(0.1)
    
    def CButtoncmd1():
        print 'Button1 changed state to ', ActivateVar1.get()
    
    def CButtoncmd2():
        print 'Button1 changed state to ', ActivateVar2.get()
    
    top = tkinter.Tk()
    
    ActivateVar1 = tkinter.DoubleVar()
    CButtonActivate1 = tkinter.Checkbutton(top, text="start1", variable=ActivateVar1, command=CButtoncmd1)
    CButtonActivate1.pack()
    
    ActivateVar2 = tkinter.DoubleVar()
    CButtonActivate2 = tkinter.Checkbutton(top, text="start2", variable=ActivateVar2, command=CButtoncmd2)
    CButtonActivate2.pack()
    
    # Run threads to monitor the state variables and set the lights
    run = True
    t1 = threading.Thread(target=lightControl, args=(1, ActivateVar1))
    t1.daemon = True
    t1.start()
    t2 = threading.Thread(target=lightControl, args=(2, ActivateVar2))
    t2.daemon = True
    t2.start()
    
    # Run tkinter's main loop
    top.mainloop()
    
    # Exit when the tkinter loop exits
    print 'Exiting program'
    run = False
    t1.join()
    t2.join()
    

    没有必要为此使用多处理。 Python 的threading 模块可以正常工作并且更简单,因为它不需要特殊代码来共享变量。仅当您需要使用多个核心时才需要多处理(GIL 将您锁定在单个核心上)。这里threading 以循环方式为所有不同的线程提供服务。由于您在这些循环中休眠,因此您不会占用太多 CPU 时间,threading 工作正常。

    【讨论】:

    • 嘿,非常感谢。我不得不稍微修改一下代码,特别是我添加了第二个灯光控制功能,然后更改了第二个线程来控制该功能。另外,感谢您向我展示如何正确关闭程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2017-01-27
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    相关资源
    最近更新 更多