我有一个Python程序,它执行以下操作: 1)无休止地等待com端口一个命令字符 2)在字符接收时,启动一个新线程来执行特定的代码
如果收到新命令,我需要做的是: 1)杀死前一个帖子 2)推出一个新的
我在这里和那里读到这样做并不是正确的方法。 知道我需要在同一个过程中执行此操作的最佳方法是什么,所以我想我需要使用线程......
答案 0 :(得分:1)
我建议你采用两种不同的方法:
答案 1 :(得分:0)
可能希望在单独的线程中运行串行端口。当它接收到一个字节时将该字节放入队列中。让主程序循环并检查队列以决定如何处理它。从主程序中,您可以使用join来终止线程并启动一个新线程。您可能还想查看一个线程池,看看它是否是您想要的。
ser = serial.Serial("COM1", 9600)
que = queue.Queue()
def read_serial(com, q):
val = com.read(1)
q.put(val)
ser_th = threading.Thread(target=read_serial, args=(ser, que))
ser_th.start()
th = None
while True:
if not que.empty():
val = que.get()
if val == b"e":
break # quit
elif val == b"a":
if th is not None:
th.join(0) # Kill the previous function
th = threading.Thread(target=functionA)
th.start()
elif val == b"b":
if th is not None:
th.join(0) # Kill the previous function
th = threading.Thread(target=functionB)
th.start()
elif val == b"c":
if th is not None:
th.join(0) # Kill the previous thread (functionA)
th = threading.Thread(target=functionC)
th.start()
try:
ser.close()
th.join(0)
except:
pass
如果您正在创建并加入大量线程,您可能希望只有一个函数来检查要运行的命令。
running = True
def run_options(option):
if option == 0:
print("Running Option 0")
elif option == 1:
print("Running Option 1")
else:
running = False
while running:
if not que.empty():
val = que.get()
run_options(val)
答案 2 :(得分:0)
让我通过添加代码结构的示例来更加精确地解决我的问题。
假设同步functionA仍然在运行,因为在内部等待特定事件,如果收到命令“c”,我需要停止functionA并启动functionC。
def functionA():
....
....
call a synchronous serviceA that can take several seconds even more to execute
....
....
def functionB():
....
....
call a synchronous serviceB that nearly returns immediately
....
....
def functionC():
....
....
call a synchronous serviceC
....
....
#-------------------
def launch_async_task(function):
t = threading.Thread(target=function, name="async")
t.setDaemon(True)
t.start()
#------main----------
while True:
try:
car = COM_port.read(1)
if car == "a":
launch_async_task(functionA)
elif car == "b":
launch_async_task(functionB)
elif car == "c":
launch_async_task(functionC)
答案 3 :(得分:0)
好吧,我终于使用了一段使用ctypes lib的代码来提供某种杀戮线程功能。 我知道这不是一个干净的方法,但在我的情况下,线程没有共享资源,所以它不会产生任何影响......
如果可以提供帮助,可以在网上轻松找到这段代码:
def terminate_thread(thread):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")