如何在Python中实现多线程?[套接字编程]
我试图在客户机中创建一个单独的线程,以非阻塞方式从服务器套接字恢复消息。由于我的原始代码太长,而且为了理解它而解释起来有点麻烦,所以我创建了一个示例程序,重点介绍我想要做的事情。我尝试创建两个独立的线程,比如如何在Python中实现多线程?[套接字编程],python,multithreading,python-3.x,sockets,Python,Multithreading,Python 3.x,Sockets,我试图在客户机中创建一个单独的线程,以非阻塞方式从服务器套接字恢复消息。由于我的原始代码太长,而且为了理解它而解释起来有点麻烦,所以我创建了一个示例程序,重点介绍我想要做的事情。我尝试创建两个独立的线程,比如线程t1和线程t2线程t1轮询套接字以检查是否有任何接收到的数据,而线程t2执行分配给它的任何任务。我希望它做的是,线程t1总是轮询,如果收到数据,它会在屏幕上打印数据,线程t2并行执行它正在做的任何事情。但是,由于某些原因,我无法让它工作 我的示例程序是: import threading
线程t1
和线程t2
<代码>线程t1轮询套接字以检查是否有任何接收到的数据,而线程t2
执行分配给它的任何任务。我希望它做的是,线程t1
总是轮询,如果收到数据,它会在屏幕上打印数据,线程t2
并行执行它正在做的任何事情。但是,由于某些原因,我无法让它工作
我的示例程序是:
import threading
import time
import threading
from time import sleep
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 5555))
s.setblocking(0)
s.sendall(str.encode('Initial Hello'))
def this_thing():
while True:
try:
data = s.recv(4096)
print(data.decode('utf-8'))
except:
pass / break #not sure which one to use. Neither of it works
def that_thing():
for i in range(10000):
sleep(3)
s.sendall(str.encode('Hello')
print('happening2')
threading.Thread(target=this_thing(), args=[]).start()
threading.Thread(target=that_thing(), args=[]).start()
注意:服务器套接字是一个简单的服务器,如果收到消息,它会向所有连接的套接字发送消息。
当我通过
线程t1
中的异常来运行程序时,只有线程t2
保持运行。也就是说,线程t1
没有收到从服务器发送的任何数据发生这种情况的原因是“target”参数接受了一个可调用的对象
从docs.python.org/2/library/threading.html
“target是run()方法调用的可调用对象”
在你的版本中
threading.Thread(target=this_thing(), args=[]).start()
threading.Thread(target=that_thing(), args=[]).start()
当您说target=this_thing()时,它将尝试计算对该_thing调用的值,在您的情况下,它将进入while True循环,然后如果要完成,它将计算为None
您要做的是将这两行替换为
threading.Thread(target=this_thing, args=[]).start()
threading.Thread(target=that_thing, args=[]).start()
请注意,您现在正在传入函数本身。函数是可调用的对象。python 3+的正确解决方案不是多线程,而是异步 查看David Beazley关于此事的精彩演讲(49分钟):
Asyncio/sockets示例:您不应该传入except块,捕获异常并记录它,或者只是打印它。若要捕获任何可以执行的异常,请尝试:code(),但异常为e:print(e)。异常越具体越好。@chatton:异常是:
[WinError 10035]非阻塞套接字操作无法立即完成
,这是有道理的,但是如果我将套接字更改为阻塞,它永远不会真正离开线程t1
,直到我收到一条我不想做的消息。有没有办法解决这个问题?threading.Thread(target=this_thing(),args=[]).start(),我很确定目标应该是函数本身,而不是函数调用的结果。target=this_thing()->target=this_thing我认为现在发生的事情是,在创建第一个线程的过程中,它被卡在一个无限循环中,这个东西和那个东西是可调用的对象。您应该能够简单地将target=this\u thing()更改为target=this\u thing,对那个东西也是一样