pyserial 使用线程的小例子 [英] Small Example for pyserial using Threading
问题描述
谁能给我一个小而简单的例子,说明如何在 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.read
和 ser.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
和 的对象
作为属性.self
的 Task1
和 Task2
方法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屋!