我有一个远程安装的BeagleBone Black,需要控制测量设备,平移/倾斜云台,上传测量数据,托管telnet服务器,...... 我正在使用Python 2.7 这是我需要编程的第一个项目,因此出现了很多问题。 我最想知道我所做的是否是一种合理的方式来处理我需要的东西,以及为什么某些事情不符合我的想法。
某些模块需要协同工作并共享数据。当telnet用户请求平移/倾斜头的位置时,最好的例子是telnet模块。
据我了解,服务器正在阻止该程序,因此我使用gevent / Greenlets从“main”脚本运行它。 剥离版本:
from gevent import monkey; monkey.patch_all() # patch functions to use gevent
import gevent
import gevent.server
from telnetsrv.green import TelnetHandler, command
__all__ = ["MyTelnetHandler", "start_server"] # used when module is loaded as "from teln import *"
class MyTelnetHandler(TelnetHandler):
"""Telnet implementation."""
def writeerror(self, text):
"""Write errors in red, preceded by 'ERROR: '."""
TelnetHandler.writeerror(self, "\n\x1b[31;5;1mERROR: {}\x1b[0m\n".format(text))
@command(["exit", "logout", "quit"], hidden=True)
def dummy(self, params):
"""Disables these commands and get them out of the "help" listing."""
pass
def start_server():
"""Server constructor, starts server."""
server = gevent.server.StreamServer(("", 2323), MyTelnetHandler.streamserver_handle)
print("server created")
try:
server.serve_forever()
finally:
server.close()
print("server finished")
"""Main loop"""
if __name__ == "__main__":
start_server()
#! /usr/bin/env python
# coding: utf-8
from gevent import monkey; monkey.patch_all() # patch functions to gevent versions
import gevent
from gevent import Greenlet
import teln # telnet handler
from time import sleep
from sys import exit
"""Main loop"""
if __name__ == "__main__":
thread_telnet = Greenlet(teln.start_server)
print("greenlet created")
thread_telnet.start()
print("started")
sleep(10)
print("done sleeping")
i = 1
try:
while not thread_telnet.ready():
print("loop running ({:03d})".format(i))
i += 1
sleep(1)
except KeyboardInterrupt:
print("interrupted")
thread_telnet.kill()
print("killed")
exit()
最后一个主循环需要运行更多功能。
的问题:
这是同时运行流程/功能的合理方式吗?
如何让telnet模块中的函数从第三个模块调用函数,控制头部?
如何确保头部不受telnet模块以及主脚本(运行某种计划)的控制?
在teln模块的“def start_server()”函数中,启动和停止服务器时会调用两个打印命令。我没有看到这些出现在终端中。可能会发生什么?
当我从远程计算机打开一个telnet会话,然后关闭它时,我得到以下输出(程序一直在运行):
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py", line 536, in run
result = self._run(*self.args, **self.kwargs)
File "/usr/local/lib/python2.7/dist-packages/telnetsrv/telnetsrvlib.py", line 815, in inputcooker
c = self._inputcooker_getc()
File "/usr/local/lib/python2.7/dist-packages/telnetsrv/telnetsrvlib.py", line 776, in _inputcooker_getc
ret = self.sock.recv(20)
File "/usr/local/lib/python2.7/dist-packages/gevent/_socket2.py", line 283, in recv
self._wait(self._read_event)
File "/usr/local/lib/python2.7/dist-packages/gevent/_socket2.py", line 182, in _wait
self.hub.wait(watcher)
File "/usr/local/lib/python2.7/dist-packages/gevent/hub.py", line 651, in wait
result = waiter.get()
File "/usr/local/lib/python2.7/dist-packages/gevent/hub.py", line 898, in get
return self.hub.switch()
File "/usr/local/lib/python2.7/dist-packages/gevent/hub.py", line 630, in switch
return RawGreenlet.switch(self)
cancel_wait_ex: [Errno 9] File descriptor was closed in another greenlet
Fri Sep 22 09:31:12 2017 <Greenlet at 0xb6987bc0L: <bound method MyTelnetHandler.inputcooker of <teln.MyTelnetHandler instance at 0xb69a1c38>>> failed with cancel_wait_ex
在尝试不同的事情以了解greenlet如何工作时,我收到了类似的(“cancel_wait_ex:[Errno 9]文件描述符在另一个greenlet中关闭”)错误消息经常。 我一直在寻找,但无法找到/了解正在发生的事情和我应该做的事情。