Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:套接字和线程?_Python_Multithreading_Sockets - Fatal编程技术网

Python:套接字和线程?

Python:套接字和线程?,python,multithreading,sockets,Python,Multithreading,Sockets,我有一个设计问题: 我有两个线程,一个心跳/控制线程和一个messagehandler线程 两者共享同一个套接字,但是messageHandler线程只发送消息,从不接收消息。心跳线程发送和接收(接收消息并对心跳作出反应) 问题是我不确定这是否安全。我自己认为,没有实现任何机制来查看套接字是否正在使用那么,通过python共享套接字是否自动实现线程安全? 如果不是,我之所以把它们放在一个单独的线程中,是因为心跳比消息处理更重要。这意味着,如果它被消息淹没,它仍然需要进行心跳。因此,如果我必须实现

我有一个设计问题:

我有两个线程,一个心跳/控制线程和一个messagehandler线程

两者共享同一个套接字,但是messageHandler线程只发送消息,从不接收消息。心跳线程发送和接收(接收消息并对心跳作出反应)

问题是我不确定这是否安全。我自己认为,没有实现任何机制来查看套接字是否正在使用那么,通过python共享套接字是否自动实现线程安全?


如果不是,我之所以把它们放在一个单独的线程中,是因为心跳比消息处理更重要。这意味着,如果它被消息淹没,它仍然需要进行心跳。因此,如果我必须实现一个bolt,那么如果我的心跳/控制线程需要发送心跳,我是否可以确定优先级?

我不知道如何在Python级别确定优先级

因此,我建议使用2个进程,而不是线程,并在操作系统级别确定优先级。在Unix上,您可以使用os.nice()来完成此操作


然后,您需要使用两个套接字,共享问题将同时得到解决。

如果两个线程都是客户端线程,最好打开两个客户端套接字,一个用于心跳,另一个用于通信。

不幸的是,多线程共享的套接字不是线程安全的。请考虑两个线程在没有锁的情况下运行的缓冲区

通常的实现方法是使用两个套接字,就像ftp所做的一样。cmd socket和msg socket

如果您想通过一个套接字实现这一点,您可以将不同类型的MSG放入不同的队列中,然后使用第三个线程使用该队列并通过唯一的套接字发送它们


通过这种方式,您可以将heartbeat msg priori控制为data msg。

一种代替使用第三个线程的更好方法是使用
threading.Lock()
来保护套接字资源,因为这样就不需要第三个线程。与使用第三个线程相比,您的开销更低,延迟更少

import threading

lock = threading.Lock()

def sendfunction(sock, data):
    with lock:
        sock.send(data)
您可以从任一线程调用它,但一次只允许一个线程调用
sock.send
。当一个线程到达另一个线程已经锁定的锁时,它将休眠,直到另一个线程释放该锁,然后它将获取该锁并重复该过程

线程模块包含
Lock
RLock
Condition
,它们在处理多个线程时都非常有用,您会发现花时间熟悉它们及其用法非常值得

在处理每条消息之前,您可以通过检查当前时间与上次发送心跳的时间来将心跳合并到消息处理中,这样可以防止消息泛滥导致心跳无法发送。问题是,如果您的消息处理代码未运行,则不会发送心跳。您可以通过让消息处理代码在间隔上获取一条伪消息来缓解这种情况,以允许它检查是否需要发送心跳信号,并忽略该伪消息

你应该尽量少用线程(目标是一个线程),但是在你的情况下,一个线程可能是可以的,因为它将花费大部分时间睡眠。但是,您不应该使用守护进程线程,因为它们没有正确关闭。虽然在您的情况下,如果没有正确关闭,损坏可能不存在,但仍可能引发某种类型的故障(错误消息),看起来很糟糕


我不同意多套接字方法,因为我认为它实际上会使情况复杂化。您会发现有许多类型的网络服务/应用程序将心跳和消息合并到一个套接字字节流中。

在一个线程上读取并从另一个线程发送是线程安全的?有人可以通过@collateral解决上述问题吗?我有同样的怀疑,我有同样的怀疑。