代替使用第三个线程的更好方法是使用threading.Lock()
来保护套接字资源,因为这消除了对第三个线程的需要。与使用第三个线程相比,您的开销和延迟更少。
import threading
lock = threading.Lock()
def sendfunction(sock, data):
with lock:
sock.send(data)
您可以从任一线程调用它,但一次只允许一个线程调用sock.send
. 当一个线程到达已经被另一个线程锁定的锁时,它将休眠,直到另一个线程释放锁,然后它将获取锁并重复该过程。
threading 模块包含Lock
、RLock
和Condition
,它们在处理多个线程时都非常有用,您会发现非常值得花时间熟悉它们及其用法。
您可以通过在处理每条消息之前检查当前时间与上次发送心跳的时间来将心跳合并到消息处理中,这样可以防止消息泛滥导致无法发送心跳。问题是如果您的消息处理代码没有运行,那么就不会发送心跳。您可以通过让您的消息处理代码每隔一段时间获取一条虚拟消息以允许它检查它是否需要发送心跳并忽略虚拟消息来缓解这种情况。
您应该尽量少用线程(针对单个线程),但是在您的情况下,线程可能没问题,因为它大部分时间都在睡觉。但是,您不应该使用守护线程,因为它们没有正确关闭。尽管在您的情况下可能不存在损坏,但如果它没有正确关闭,它仍然可能会引发某种看起来很糟糕的故障(错误消息)。
我不同意多套接字方法,因为我认为它实际上会使情况复杂化。您会发现许多类型的网络服务/应用程序将心跳和消息合并到单个套接字字节流中。