我有一份工作'接受来自客户端的请求的服务器(有8个客户端从另一台机器发送请求)。然后,服务器提交一份“工作”作业。 (一个' job'只是一个将结果文件写入磁盘的可执行文件),以及一个' job manager'线程等待工作完成。作业完成后,它会向客户端发送一条消息,表明结果文件已准备好复制回客户端。
在主线程上,我使用select
来读取来自客户端的传入连接以及作业请求:
readable, writable, exceptional = select.select(inputs, [], [])
其中inputs
是已接受连接(套接字)的列表,此列表还包含server
套接字。所有套接字都设置为非阻塞。据我所知,如果对select
的此调用返回非空readable
,则表示inputs
的某些元素有等待读取的传入数据。
我正在使用以下逻辑读取数据(SIZE
是常量):
for s in readable:
if s is not server:
try:
socket_ok = True
data = s.recv(SIZE)
except socket.error as e:
print ('ERROR socket error: ' + str(e) )
socket_ok = False
except Exception as e:
print ('ERROR error reading from socket: ' + str(e))
socket_ok = False
if not socket_ok:
# do something
我有两个问题:
[Errno 110] Connection timed out
例外情况,而且我不明白为什么 - 如果我有一个可读的套接字,那是不是意味着它有一些数据需要读取? #do something
部分。我可以做一个清理工作。 - 删除超时套接字请求的正在运行的作业,并从列表中删除死套接字。但我无法让客户知道它应该停止等待这些工作。结果。理想情况下,我想以某种方式重新连接,因为工作本身会继续运行并产生我不想丢弃的结果。 编辑我现在意识到作业管理器线程也可以通过Queue
实例访问套接字 - 如果作业完成,则线程发送作业& #39;通过相关套接字的消息 - 所以同一套接字的send
和recv
方法可能导致某种竞争条件?但无论如何,我不知道这是如何导致连接超时的。错误。
答案 0 :(得分:0)
一个只是猜测并且似乎有效的解决方案:在客户端,我使用阻塞recv
方法从服务器获取作业完成的消息。由于作业可能需要很长时间(例如,如果运行作业的集群资源不足),我猜测套接字等待可能是导致超时的原因。因此,我不是在阻塞模式下使用recv
,而是在超时5秒内使用它,因此我可以每隔5秒向服务器发送一条虚拟消息,以保持连接活动,直到收到消息。现在我不再得到异常(在服务器端)。