2016-11-29 75 views
1

我正在使用类似的代码作为波纹管来控制RGB LED灯带,随机值每隔几秒进来一次,并且正在创建3个线程来控制3个单独的颜色。Python线程在加入后不关闭

import time 
from ast import literal_eval 
import threading 
from random import randint 
t=[] 
myR =0 
myG =0 
myB =0 
temp = 0 
pins = [17,22,24] 
myColours = [myR,myG,myB] 
red_pin = 17 
green_pin = 22 
blue_pin = 24 

def change_led_color(rgb): 
    global myR 
    global myG 
    global myB 
    y = 0 
    threads = [] 
    for colour in rgb: 
    t = threading.Thread(target=leds,name=pins[y] ,args=(y,myColours[y],colour,pins[y])) 
    threads.append(t) 
    y += 1 
    for y in threads: 
    y.start() 
    for y in threads: 
    y.join() 

def leds(index,start,end,pin): 
    temp=0 
    for i in range(start,end): 
    time.sleep(0.01) 
    temp = i 
    global myColours 
    print 'pin', pin, 'started at: ',start,' ended is: ', temp 
    myColours[index] = end 

def set_colours(): 
    print '..................................................................',t 
    print threading.activeCount(),'threads \n' 
    threading.Timer(2, set_colours).start() 
    change_led_color(t) 
set_colours() 

def get_data(): 
    while True: 
     global t 
     t = (randint(0,255),randint(0,255),randint(0,255)) 
     time.sleep(2) 
threading.Thread(target=get_data).start() 

上面运行正常,但反应是很奇怪的,而不是让所有的三种颜色的线程结束时,我有时会超过预期,大部分的时间中的至少一个为0,像线程永远不会运行! 我假设我以某种方式滥用穿线。

例如,结果

.................................................................. (187, 223, 42) 
3 threads 

pin 24 started at: 205 ended is: 0 
pin 22 started at: 170 ended is: 222 
pin 17 started at: 107 ended is: 186 
.................................................................. (202, 115, 219) 
3 threads 

pin 22 started at: 223 ended is: 0 
pin 17 started at: 187 ended is: 201 
.................................................................. (244, 35, 194) 
5 threads 

pin 22 started at: 115 ended is: 0 
pin 24 started at: 42 ended is: 218 
pin 17 started at: 202 ended is: 243 
pin 24 started at: 42 ended is: 193 
.................................................................. (54, 25, 72) 
3 threads 

pin 17 started at: 244 ended is: 0 
pin 22 started at: 35 ended is: 0 
pin 24 started at: 194 ended is: 0 
+0

你的假设是正确的。任何时候你在线程代码中看到'global',你都知道你可能做错了。 –

+2

是否有任何理由在这里实际使用线程?为什么不只是更新三个LED,因为更新几乎不需要时间? – chthonicdaemon

+0

我使用线程的原因是我试图在变化之间实现平滑过渡,因此使用'for i in range..'来同时执行三种颜色的转换。 –

回答

1

您是否考虑过GIL(全局解释器锁)? https://wiki.python.org/moin/GlobalInterpreterLock

Python有一个GIL,它不允许多个线程从一个进程运行。当你运行你的代码时,它将作为一个python进程运行。您正在尝试从python中不允许的相同进程启动线程。

如果你想并行执行一些操作,多处理包是一个不错的选择。
https://pymotw.com/2/multiprocessing/basics.html

+0

谢谢@Tejas! 产卵过程解决了这个问题,我不能再使用'global'了,但是我通过在每个过程开始时读取LED的值来解决这个问题 –

+1

@StratosIon多线程不适合你的原因是你不再在你的线程中共享内存,这就是为什么你有问题。 –

1

不考虑其他因素(见下文),for i in range(start,end):循环将持续高达2.5秒;但你实际上每2秒产生一次新线程。

此外,该循环的实际持续时间实际上是更长的时间:

  • 每当你问一个睡眠,持续时间至少你问什么;但可能会稍微多一些。特别是当你要求1/100秒时,可能会更长一点。
  • 既然你是一个接一个地要求许多小小的睡眠,你可能会期望效果倍增;这意味着总时间了循环所for i in range(start,end):会比预期更长

尝试:

  • 使用一个等待:time.sleep(0.01 * start-end if end>start else 0)
  • 增加用于生成新线程的时候3- 4秒