我正在尝试在客户端中创建一个单独的线程,以非阻塞方式从服务器套接字恢复消息。由于我的原始代码太长而且为了理解它而需要解释一些麻烦,我已经创建了一个示例程序,专注于我想要做的事情。我尝试创建两个单独的线程,比如Thread t1
和Thread t2
。 Thread t1
轮询套接字以检查是否有任何接收到的数据,而Thread t2
执行分配给它的任何任务。我期待它做的是,Thread t1
总是轮询,如果收到数据,它会在屏幕上打印出来,并Thread 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()
注意: 服务器套接字是一个简单的服务器,如果收到消息,它会向所有连接的套接字发送消息。
当我在Thread t1
中通过突破异常运行该程序时,只有我的Thread t2
一直在运行。 I.e Thread t1
未收到服务器发送的任何数据
答案 0 :(得分:3)
发生这种情况的原因是因为“target”参数采用可调用对象。
来自docs 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()时,它会尝试计算对this_thing的调用值,在你的情况下,它会输入一个True循环,然后如果要完成它会评估为None。
您要做的是用
替换这两行threading.Thread(target=this_thing, args=[]).start()
threading.Thread(target=that_thing, args=[]).start()
请注意,您现在正在传递函数本身。函数是可调用对象。
答案 1 :(得分:0)
python 3+的正确解决方案不是多线程,而是asyncio。
查看David Beazley就此事发表的精彩演讲(49分钟): https://www.youtube.com/watch?v=ZzfHjytDceU
Asyncio /套接字示例:https://gist.github.com/gregvish/7665915