pyserial 使用线程的小例子 [英] Small Example for pyserial using Threading

查看:45
本文介绍了pyserial 使用线程的小例子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能给我一个小而简单的例子,说明如何在 pyserial 通信中使用线程.我在谷歌上搜索了三天以上,但我仍然不识字,我什至没有将它们集成在一起的工作代码

Can anyone please give me a small and simple example on how to use threading with pyserial communication. I am googling for over three days and I am still illeterate and I dont even have a working piece of code which integrate both of them

基本上我的目标是在这种情况下使用线程:

Basically I am aiming to use threading in this scenario:

在后台连续进行串行通信以从 MCU 获得特定值(例如 A).

Have a serial communication continuously go on in the back ground to attain certain value (say A) from an MCU.

停止达到值 A - 然后达到值 B...并再次开始连续达到值 A.

Stop attaining value A - then attain value B...and start continuously attaining value A again.

您可以在此处找到一些基本代码.

You can find some basic code here.

import threading
import time
import sys
import serial
import os
import time

def Task1(ser):

    while 1:

        print "Inside Thread 1"
        ser.write('\x5A\x03\x02\x02\x02\x09') # Byte ArrayTo Control a MicroProcessing Unit
        b = ser.read(7)
        print b.encode('hex')
        print "Thread 1 still going on"
        time.sleep(1)


def Task2(ser):

    print "Inside Thread 2"
    print "I stopped Task 1 to start and execute Thread 2"
    ser.write('x5A\x03\x02\x08\x02\x0F')
    c = ser.read(7)
    print c.encode('hex')
    print "Thread 2 complete"


def Main():
    ser = serial.Serial(3, 11520)
    t1 = threading.Thread(target = Task1, args=[ser])
    t2 = threading.Thread(target = Task2, args=[ser])
    print "Starting Thread 1"
    t1.start()
    print "Starting Thread 2"
    t2.start()

    print "=== exiting ==="

    ser.close()

if __name__ == '__main__':

    Main()

推荐答案

Task2 的声明没有事实依据:

There's no factual basis for the claim by Task2:

print "I stopped Task 1 to start and execute Thread 2"

您的实现启动一个线程,然后立即启动另一个而无需停止第一个.这意味着 ser.readser.write 命令可能会相互干扰.

Your implementation starts one thread then immediately starts the other without stopping the first. This means that the ser.read and ser.write commands could interfere with each other.

解决此问题的最简单方法是引入允许通信的变量:

The simplest thing you could do to address this is to introduce variables that allow communication:

import sys
import os
import time
import threading

thread_flag = None


def Report(s):
    print s
    sys.stdout.flush() # helps to ensure messages from different threads appear in the right order

def Stop():
    global thread_flag
    thread_flag = 'stop'

def Task1(ser):

    Report("Inside Thread 1")
    global thread_flag
    thread_flag = 'go'

    while True:

        Report("Thread 1 waiting for permission to read")
        while thread_flag != 'go': time.sleep( 0.001 )

        while thread_flag == 'go':
            Report("Thread 1 is reading")
            #ser.write('\x5A\x03\x02\x02\x02\x09') # Byte ArrayTo Control a MicroProcessing Unit
            #b = ser.read(7)
            #Report(b.encode('hex'))
            time.sleep(1)

        if thread_flag == 'stop': break
        else: thread_flag = 'paused'   # signals that the inner loop is done

    Report("Thread 1 complete")


def Task2(ser):

    Report("Inside Thread 2")

    global thread_flag
    thread_flag = 'pause' # signals Task1 to pause
    while thread_flag != 'paused': time.sleep(0.001) # waits for Task1 inner loop to exit
    Report("I stopped Task 1 to start and execute Thread 2")

    #ser.write('x5A\x03\x02\x08\x02\x0F')
    #c = ser.read(7)
    #Report(c.encode('hex'))

    thread_flag = 'go' # signals Thread 1 to resume
    Report("Thread 2 complete")


def Main():
    ser = None # serial.Serial(3, 11520)
    t1 = threading.Thread(target = Task1, args=[ser])
    t2 = threading.Thread(target = Task2, args=[ser])
    Report("Starting Thread 1")
    t1.start()

    time.sleep(3)
    Report("Starting Thread 2")
    t2.start()


if __name__ == '__main__':

    Main()

这种方法使用了一个全局变量,这经常被人反对.您可以改为创建带有 self.ser 的对象 selfTask1Task2 方法self.thread_flag 作为属性.

That approach uses a global variable, which is often frowned upon. You could instead make Task1 and Task2 methods of an object self that carries both self.ser and self.thread_flag as attributes.

对于任何比这更复杂的线程间通信,您需要研究锁、互斥锁和信号量(例如 threading.Lock)

For any inter-thread communication more complex than this, you need to investigate locks, mutexes and semaphores (e.g. threading.Lock)

这篇关于pyserial 使用线程的小例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆