我正在使用一个使用套接字进行通信的接口。我需要使用Threads来同时接收和发送数据。
以下代码是连续发送数据的模块的缩减版本。
我的问题是在开发过程中,我需要经常启动和停止,但似乎线程使得无法像普通脚本一样停止应用程序。需要在进程管理器中终止该进程才能重新启动它。
我有一种感觉,我误解了一些东西。
我环顾四周,但我看到了大量不一致的答案,我试图实施无济于事。我已经尝试过处理KeyboardInterrupt异常,但这不起作用。
有什么想法吗?
import socket
import sys
import threading
running = True
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 50000)
print ('connecting to %s port %s' % server_address)
sock.connect(server_address)
class TelemetryPacket:
state = "N/A"
def __init__(self, stringvalue):
self.state = stringvalue
def serialise(self):
return "%s" % (self.state)
def send(running):
try:
while (running):
telemetry = TelemetryPacket(0).serialise()
sock.sendto(telemetry.encode('utf-8'), server_address)
except KeyboardInterrupt:
print ("threads successfully closed")
running = False
def recv(running):
try:
while (running):
data = sock.recv(1)
if (data):
print("data received: %s" % data)
except KeyboardInterrupt:
print ("threads successfully closed")
running = False
a = threading.Thread(target=send, args=(running,))
a.start()
b = threading.Thread(target=recv, args=(running,))
b.start()
答案 0 :(得分:2)
您应该在主线程中捕获您的键盘中断,然后向您的子线程发送信号以退出并连接回主线程。您还应该使用更安全的线程来发送信号,例如基本的threading.Event()
,所以:
import threading
import time
exit_signal = threading.Event() # your global exit signal
def send():
while not exit_signal.is_set():
pass # whatever you need
def recv():
while not exit_signal.is_set():
pass # whatever you need
# create the threads
a = threading.Thread(target=send)
b = threading.Thread(target=recv)
# start the threads
a.start()
b.start()
# create a main thread loop
try:
while not exit_signal.is_set(): # enable children threads to exit the main thread, too
time.sleep(0.1) # let it breathe a little
except KeyboardInterrupt: # on keyboard interrupt...
exit_signal.set() # send signal to all listening threads
# join back the threads
a.join()
b.join()
# and you're done...
答案 1 :(得分:1)
问题是在键盘异常时只有主线程被杀死。 因此,您需要通知线程主线程已被杀死。
不是将运行作为参数传递,而是使用它来表示线程。这是一个示例代码。唯一不同的是,函数不作为参数运行,但它使用它来跟踪。因此,当主线程死亡时,我们将其设置为false(在代码的末尾)。
import socket
import sys
import threading
running = True
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 50000)
print ('connecting to %s port %s' % server_address)
sock.bind(server_address)
class TelemetryPacket:
state = "N/A"
def __init__(self, stringvalue):
self.state = stringvalue
def serialise(self):
return "%s" % (self.state)
def send():
try:
while (running):
telemetry = TelemetryPacket(0).serialise()
sock.sendto(telemetry.encode('utf-8'), server_address)
except KeyboardInterrupt:
print ("threads successfully closed")
def recv():
try:
while (running):
data = sock.recv(1)
if (data):
print("data received: %s" % data)
except KeyboardInterrupt:
print ("threads successfully closed")
try:
a = threading.Thread(target=send)
a.start()
b = threading.Thread(target=recv)
b.start()
while True:
pass
except KeyboardInterrupt:
print ("threads successfully closed")
running = False # Kill the threads