'polling' 指的是什么,这段代码到底在做什么?
What does 'polling' refer to and what is this code doing exactly?
我目前正在构建一个 python 脚本,用于启用和禁用交换机上的某些端口,以查看交换机将如何用于质量保证目的。我一直在使用一个名为 paramiko 的 Python 库,它实现 SSH 以连接到我想要的任何设备,我指的是我的一位队友交给的遗留代码以编写更多脚本。在遗留代码文件之一中,有一个名为 _run_poll 的函数,我不明白它到底在做什么。
我已经尝试研究 "polling" 对 SSH 的意义,但我仍然不明白当我们 运行 和 "poll" 时发生了什么。它的定义似乎有点模糊。这是函数:
def _run_poll(self, session, timeout, input_data):
interval = 0.1
maxseconds = timeout
maxcount = maxseconds / interval
i = 0
timeout_flag = False
self.info('polling (%d, %d)' % (maxseconds, maxcount))
start = datetime.datetime.now()
start_secs = time.mktime(start.timetuple())
output = ''
session.setblocking(0)
while True:
if session.recv_ready(): # returns true if data has been buffered
data = session.recv(self.bufsize) # receive data from the channel
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
if session.send_ready():
# We received a potential prompt.
# In the future this could be made to work more like
# pexpect with pattern matching.
if i < len(input_data):
data = input_data[input_idx] + '\n'
i += 1
self.info('sending input data %d' % (len(data)))
session.send(data)
self.info('session.exit_status_ready() = %s' % (str(session.exit_status_ready())))
if session.exit_status_ready():
break
# Timeout check
now = datetime.datetime.now()
now_secs = time.mktime(now.timetuple())
et_secs = now_secs - start_secs
self.info('timeout check %d %d' % (et_secs, maxseconds))
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
time.sleep(0.200)
self.info('polling loop ended')
if session.recv_ready():
data = session.recv(self.bufsize)
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
self.info('polling finished - %d output bytes' % (len(output)))
if timeout_flag:
self.info('appending timeout message')
output += '\nERROR: timeout after %d seconds\n' % (timeout)
session.close()
return output
我找不到很多在线资源来描述这里发生的事情或关于 "polling" 的一般情况。谁能帮我解释一下 "polling" 到底是什么以及这里发生了什么?
关于 Polling 的维基百科文章将其定义为:
Actively sampling the status of an external device by a client program as a synchronous activity.
在您的代码中,这意味着它定期(每 200 毫秒)检查 SSH 连接是否有任何传入数据和输出队列中的可用容量。
在编程中有两种处理异步事件的方法。
一种方法是使用中断:您的代码直到 "woken up" 才通过某种机制执行,然后才执行。必须在比代码执行位置更低的级别支持此机制。例如,微控制器内置了特定的硬件,可以中断应用程序并跳转到特定地址以开始执行指令以处理中断。
构建中断系统很困难,需要大量的工作。对于某些应用程序,这是不可能的。轮询或反复检查条件直到它变为真,然后继续执行其他操作几乎总是更容易(尽管效率较低)。
在您的示例中,请注意他如何使用 while True:
循环。 True 永远不会为 False,所以这个 while 循环只能被 break
语句打破。我们在
处找到 break 语句
if session.exit_status_ready():
break
所以该代码的作者决定连续做一些事情,直到 session.exit_status_ready()
为真。由于这是 paramiko,他很可能通过 SSH 执行了远程命令并等待命令完成并且 returns 退出代码。这个循环的要点是让程序一直卡在循环中,直到命令执行完毕并得到 returns 结果。它也可以超时:
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
因此,如果命令花费的时间超过 maxseconds
,程序将不会永远等待。
一旦退出循环,它会打印:
self.info('polling loop ended')
所以当你看到这条消息时,你就知道远程命令执行完成或超时了。
轮询的要点是反复检查某些东西,直到出现某种情况。在您的情况下,该条件是 "a remote command has finished executing" 或 "a certain amount of time has passed."
我目前正在构建一个 python 脚本,用于启用和禁用交换机上的某些端口,以查看交换机将如何用于质量保证目的。我一直在使用一个名为 paramiko 的 Python 库,它实现 SSH 以连接到我想要的任何设备,我指的是我的一位队友交给的遗留代码以编写更多脚本。在遗留代码文件之一中,有一个名为 _run_poll 的函数,我不明白它到底在做什么。
我已经尝试研究 "polling" 对 SSH 的意义,但我仍然不明白当我们 运行 和 "poll" 时发生了什么。它的定义似乎有点模糊。这是函数:
def _run_poll(self, session, timeout, input_data):
interval = 0.1
maxseconds = timeout
maxcount = maxseconds / interval
i = 0
timeout_flag = False
self.info('polling (%d, %d)' % (maxseconds, maxcount))
start = datetime.datetime.now()
start_secs = time.mktime(start.timetuple())
output = ''
session.setblocking(0)
while True:
if session.recv_ready(): # returns true if data has been buffered
data = session.recv(self.bufsize) # receive data from the channel
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
if session.send_ready():
# We received a potential prompt.
# In the future this could be made to work more like
# pexpect with pattern matching.
if i < len(input_data):
data = input_data[input_idx] + '\n'
i += 1
self.info('sending input data %d' % (len(data)))
session.send(data)
self.info('session.exit_status_ready() = %s' % (str(session.exit_status_ready())))
if session.exit_status_ready():
break
# Timeout check
now = datetime.datetime.now()
now_secs = time.mktime(now.timetuple())
et_secs = now_secs - start_secs
self.info('timeout check %d %d' % (et_secs, maxseconds))
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
time.sleep(0.200)
self.info('polling loop ended')
if session.recv_ready():
data = session.recv(self.bufsize)
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
self.info('polling finished - %d output bytes' % (len(output)))
if timeout_flag:
self.info('appending timeout message')
output += '\nERROR: timeout after %d seconds\n' % (timeout)
session.close()
return output
我找不到很多在线资源来描述这里发生的事情或关于 "polling" 的一般情况。谁能帮我解释一下 "polling" 到底是什么以及这里发生了什么?
关于 Polling 的维基百科文章将其定义为:
Actively sampling the status of an external device by a client program as a synchronous activity.
在您的代码中,这意味着它定期(每 200 毫秒)检查 SSH 连接是否有任何传入数据和输出队列中的可用容量。
在编程中有两种处理异步事件的方法。
一种方法是使用中断:您的代码直到 "woken up" 才通过某种机制执行,然后才执行。必须在比代码执行位置更低的级别支持此机制。例如,微控制器内置了特定的硬件,可以中断应用程序并跳转到特定地址以开始执行指令以处理中断。
构建中断系统很困难,需要大量的工作。对于某些应用程序,这是不可能的。轮询或反复检查条件直到它变为真,然后继续执行其他操作几乎总是更容易(尽管效率较低)。
在您的示例中,请注意他如何使用 while True:
循环。 True 永远不会为 False,所以这个 while 循环只能被 break
语句打破。我们在
if session.exit_status_ready():
break
所以该代码的作者决定连续做一些事情,直到 session.exit_status_ready()
为真。由于这是 paramiko,他很可能通过 SSH 执行了远程命令并等待命令完成并且 returns 退出代码。这个循环的要点是让程序一直卡在循环中,直到命令执行完毕并得到 returns 结果。它也可以超时:
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
因此,如果命令花费的时间超过 maxseconds
,程序将不会永远等待。
一旦退出循环,它会打印:
self.info('polling loop ended')
所以当你看到这条消息时,你就知道远程命令执行完成或超时了。
轮询的要点是反复检查某些东西,直到出现某种情况。在您的情况下,该条件是 "a remote command has finished executing" 或 "a certain amount of time has passed."