键盘中断,套接字和线程 [英] Keyboard interrupt, sockets and Threads

查看:70
本文介绍了键盘中断,套接字和线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用套接字进行通信的接口上工作.我需要使用线程才能同时接收和发送数据.

I'm working on an interface that communicates using sockets. I need to use Threads in order to receive and send data at the same time.

下面的代码是持续发送数据的模块的简化版本.

The below code is a cut down version of the module that continuously sends data.

我的问题是,在开发过程中,我需要经常启动和停止该程序,但是似乎线程使得无法像正常脚本一样停止该应用程序.需要在进程管理器中终止该进程才能重新启动它.

My issue is that during development, I need to start and stop this frequently, but it seems threads makes it impossible to stop the application like you can a normal script. The process needs to be killed in process manager in order to restart it.

我有一种误解.

我环顾四周,但是看到大量不一致的答案,这些尝试都没有实现.我已经尝试处理KeyboardInterrupt异常,但这是行不通的.

I've looked around but I'm seeing loads of inconsistent answers which I've tried to implement to no avail. I've tried handling the KeyboardInterrupt exception and that doesn't work.

有什么想法吗?

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()

推荐答案

您应该在主线程中捕获键盘中断,然后向子线程发送信号以退出并重新加入主线程.您还应该使用更多线程安全的信号进行传输,例如基本的threading.Event(),因此:

You should be capturing your your keyboard interrupt in the main thread and then sending a signal to your child threads to exit and join back to the main thread. You should also use something more thread safe for signaling like the basic threading.Event(), so:

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...

这篇关于键盘中断,套接字和线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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