线程不在我的Python代码中

时间:2015-10-30 17:48:26

标签: python multithreading python-3.x python-multithreading

首先,我自己从在线教程中学习了Python,并且(大部分)通过实践来学习,所以我可能在我的代码中做了一些奇怪的事情。 :) 所以,我正在使用Raspberry Pi开发我的第一个更大的项目,为此我需要并行运行的代码。我写了这部分代码来管理一个简单的D-pad:

有问题的代码

import threading
import time
import pigpio


# input from the D-pad goes to these pins
BUTT_UP = 12
BUTT_LEFT = 16
BUTT_CENTER = 25
BUTT_RIGHT = 20
BUTT_DOWN = 21


class dpad_monitoring(threading.Thread):
    '''thread for monitoring the D-Pad'''

    def __init__(self, thread_ID, butt_up, butt_left, butt_center, butt_right, butt_down, res = 10.00):

        threading.Thread.__init__(self)
        self.running = True
        self.thread_ID = thread_ID

        # number of checks per sec
        self.res = res

        # key pins
        self._pins = [butt_up, butt_left, butt_center, butt_right, butt_down]

        #key monitor
        self.last_pressed = 0

        '''key numbers:
         UP      LEFT    CENTER     RIGHT     DOWN
          1       2        3          4         5       '''

        # setting up GPIO
        self.pi = pigpio.pi()
        for i in range(0, len(self._pins)):
            self.pi.set_mode(self._pins[i], pigpio.INPUT)
            self.pi.set_pull_up_down(self._pins[i], pigpio.PUD_UP)

    def stop(self):
        '''stopping the thread cleanly'''
        self.pi.stop()
        self.running = False

    def run(self):
        '''checks which button is pressed as many times per sec as specified 
            in the res variable in init. If any of them is pressed, it suspends itself
            until self.last_pressed is set to 0 again by main()'''


        while self.running:

            states = []
            for i in range(0, len(self._pins)):
                state = not self.pi.read(self._pins[i])  # pi.read returns 1L if the pin is high, 
                states.append(state)                #   what means the button is not pressed, 0L when pressed

            for i in range(0, len(states)):
                if states[i]:
                    self.last_pressed = i+1

            '''UGLY AS SHIT but works now, will change to locks after the code works'''
            if self.last_pressed != 0 :
                while self.last_pressed != 0:
                    pass
            else:
                time.sleep(1/self.res)


            print 'im groot'  # for debugging



def main():

    print 'ok' #debug

    dpad = dpad_monitoring(0, BUTT_UP, BUTT_LEFT, BUTT_CENTER, BUTT_RIGHT, BUTT_DOWN)
    dpad.run()

    print 'okey' #debug again 

    while i != 3:

        i = dpad.last_pressed
        if i == 1:
            print 'UP'
            dpad.last_pressed = 0
        if i == 2:
            print 'LEFT'
            dpad.last_pressed = 0
        if i == 4:
            print 'RIGHT'
            dpad.last_pressed = 0
        if i == 5:
            print 'DOWN'
            dpad.last_pressed = 0

    print 'CENTER, stopping'
    time.sleep(0.5)
    dpad.stop()

if __name__ == '__main__':
    main()

问题是当我运行代码时,我得到了这个:

ok
im groot
im groot
im groot
im groot
im groot
im groot

... (endless groot)

所以似乎代码卡在dpad.run()上。现在AFAIK,线程的主要观点是代码在调用run()函数后继续并且可以与线程对象进行交互,所以我不知道他将会发生什么。各位专家能帮帮我吗? (由于dpad.run()之后的代码从未运行,我不知道它是否有效,它可能都是垃圾。:P

奇怪的是,这个简单的测试代码没有问题:

酷代码:

import threading
import time

class thread1(threading.Thread):

    def __init__(self, threadID, start_from):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.i = start_from
        self.running = True

    def run(self):
            while self.running:
                time.sleep(1)
                self.i = self.i+1

    def stop(self):
        self.running = False

class thread2(threading.Thread):

    def __init__(self, threadID, start_from):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.i = start_from
        self.running = True

    def run(self):
            while self.running:
                time.sleep(0.5)
                self.i = self.i+10

    def stop(self):
        self.running = False

thread1 = thread1(1, 10)
thread2 = thread2(2, 1)

thread1.start()
thread2.start()

for j in range(30):
    print thread1.i, thread2.i
    time.sleep(0.3)

thread1.stop()
thread2.stop()

输出

10 1
10 1
10 11
10 11
11 21
11 31
11 31
12 41
12 41
12 51
13 61
13 61
13 71
13 71
14 81
14 91
14 91
15 101
15 101
15 111
16 121
16 121
16 131
16 131
17 141
17 151
17 151
18 161
18 161
18 171


------------------
(program exited with code: 0)
Press return to continue

所以我得到了主线程加上另外两个并行运行,不太可能是前面的代码。他会怎么样?

1 个答案:

答案 0 :(得分:2)

而不是

dpad.run()

dpad.start()

直接调用run()时,您将跳过整个线程功能并将其用作常规类。