【问题标题】:What does 'polling' refer to and what is this code doing exactly?“轮询”指的是什么,这段代码到底在做什么?
【发布时间】:2019-05-29 19:56:13
【问题描述】:

我目前正在构建一个 python 脚本,用于启用和禁用交换机上的某些端口,以查看交换机将如何操作以达到质量保证目的。我一直在使用一个名为 paramiko 的 Python 库,它实现了 SSH 以连接到我想要的任何设备,我指的是我的一位队友提供的遗留代码来编写更多脚本。在其中一个遗留代码文件中,有一个名为 _run_poll 的函数,我不明白它到底在做什么。

我已经尝试对“轮询”对 SSH 的含义进行一些研究,但我仍然不明白当我们运行“轮询”时会发生什么。它的定义似乎有点模糊。这是函数:

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

我找不到很多在线资源来描述这里发生的事情或一般的“投票”。谁能帮我解释一下究竟什么是“投票”以及这里发生了什么?

【问题讨论】:

    标签: python networking ssh paramiko polling


    【解决方案1】:

    在编程中处理异步事件有两种方式。

    一种方法是使用中断:您的代码在被某种机制“唤醒”之前不会执行,然后它会执行。必须在比代码执行位置更低的级别支持此机制。例如,微控制器具有内置的特定硬件,可以中断应用程序并跳转到特定地址以开始执行指令以处理中断。

    构建中断系统很困难,并且需要大量工作。对于某些应用程序,这是不可能的。轮询或反复检查一个条件直到它变为 True 几乎总是更容易(尽管效率较低),然后继续执行其他操作。

    在您的示例中,请注意他如何使用while True: 循环。 True 永远不会是 False,所以这个 while 循环只能被 break 语句打破。我们在

    处找到了break语句
    if session.exit_status_ready():
                break
    

    因此,该代码的编写者决定持续执行某些操作,直到 session.exit_status_ready() 为 True。由于这是 paramiko,因此他很可能通过 SSH 执行了一个远程命令,并且正在等待命令完成并返回一个退出代码。这个循环的目的是让程序一直停留在循环中,直到命令完成执行并返回结果。它也可以超时:

    if et_secs > maxseconds:
                self.info('polling finished - timeout')
                timeout_flag = True
                break
    

    因此,如果命令需要的时间超过maxseconds,程序就不会一直等待。

    一旦退出循环,就会打印:

    self.info('polling loop ended')
    

    所以当你看到这条消息时,你就知道远程命令执行完毕或超时了。

    轮询的目的是反复检查某些东西,直到出现某种情况。在您的情况下,该条件是“远程命令已完成执行”或“已经过了一定时间”。

    【讨论】:

    • 这很有意义。非常感谢!
    • 如果您不介意接受我的回答,我将不胜感激!
    【解决方案2】:

    关于Polling的维基百科文章将其定义为:

    客户端程序主动采样外部设备的状态作为同步活动。


    在您的代码中,这意味着它会定期(每 200 毫秒)检查 SSH 连接是否有任何传入数据和输出队列中的可用容量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-08
      • 2016-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多