Python Errno 9 Mac OS X中的错误文件描述符 [英] Python Errno 9 Bad file descriptor in Mac OS X

查看:106
本文介绍了Python Errno 9 Mac OS X中的错误文件描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面的代码多次运行而没有任何问题 在Linux中互为对方:

I have the following code running without any problem multiple times after each other in Linux:

def test_ftp(ftpserver):
    with FTP() as f:
        f.connect("localhost", port=ftpserver.server_port)
        f.login("M1", "bachmann")
        f.cwd("/")
        f.mkd("FOO")
        f.quit()

相同的测试只能在MacOS X中运行一次,之后它将挂起.重新启动计算机是我重新运行测试的唯一方法.

The same tests can only be run once in MacOS X, after that it will simply hang. Rebooting the machines, is the only way I can re-run the tests.

ftpserver是在 pytest-localftpserver 中定义的测试装置,我正在发布代码出于此原因,我怀疑这是导致错误的原因:

ftpserver is a test fixture defined in pytest-localftpserver, I am posting the code for this fixture here for the reason that I suspect that it is the cause of error:

class MPFTPServer(multiprocessing.Process):

    def __init__(self, username, password, ftp_home, ftp_port, **kwargs):
        self._server = SimpleFTPServer(username, password, ftp_home, ftp_port)
        self.server_home = self._server.ftp_home
        self.anon_root = self._server.anon_root
        self.server_port = self._server.ftp_port

        super().__init__(**kwargs)

    def run(self):
        self._server.serve_forever()

    def join(self):
        self._server.stop()

    def stop(self):
        self._server.stop()

@pytest.fixture(scope="session", autouse=True)
def ftpserver(request):
    """The returned ``ftpsever`` provides a threaded instance of
    ``pyftpdlib.servers.FTPServer`` running on localhost.
    ...
    """

    from pytest_localftpserver.plugin import MPFTPServer
    ftp_user = os.getenv("FTP_USER", "fakeusername")
    ftp_password = os.getenv("FTP_PASS", "qweqwe")
    ftp_home =  os.getenv("FTP_HOME", "")
    ftp_port = int(os.getenv("FTP_PORT", 0))
    server = MPFTPServer(ftp_user, ftp_password, ftp_home, ftp_port)
    # This is a must in order to clear used sockets
    server.daemon = True
    server.start()
    yield server
    server.join()

您能说出为什么此代码在Linux中可重复运行"但在MacOSX中不能重复运行吗?

Can you tell why this code "works repeatedly" in Linux but not in MacOSX?

进一步挖掘,我发现ftp服务器甚至无法启动,因此挂起了.代码崩溃,并显示以下消息:

Digging a bit further, I found that the ftp server will not even start, hence the hanging. The code crashes with the following message:

    Process MPFTPServer-1:
    Traceback (most recent call last):
      File "/opt/pkg/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
        self.run()
      File "/Users/w/.virtualenvs/controller_config/lib/python3.5/site-packages/pytest_localftpserver/plugin.py", line 81, in run
        self._server.serve_forever()
      File "/Users/w/.virtualenvs/controller_config/lib/python3.5/site-packages/pyftpdlib/servers.py", line 207, in serve_forever
        self.ioloop.loop(timeout, blocking)
      File "/Users/w/.virtualenvs/controller_config/lib/python3.5/site-packages/pyftpdlib/ioloop.py", line 348, in loop
        poll(soonest_timeout)
      File "/Users/w/.virtualenvs/controller_config/lib/python3.5/site-packages/pyftpdlib/ioloop.py", line 709, in poll
        timeout)
    OSError: [Errno 9] Bad file descriptor

推荐答案

好,显然

如果在派生和创建分支之前创建了IOLoop,就会发生这种情况 然后尝试在子进程中使用它.如果您要使用fork, 您必须先完成此操作,然后再创建单例IOLoop.

that's what happens if you create an IOLoop before a fork and then try to use it in the child process. If you're going to use fork, you have to do it before anything creates the singleton IOLoop.

因此解决方案只是在run方法内部而不是在__init__中启动服务器实例:

So the solution was simply to start the server instance inside the run method, instead in __init__:

class MPFTPServer(multiprocessing.Process):

    def __init__(self, username, password, ftp_home, ftp_port, **kwargs):
        self.username = username
        self.password = password
        self.server_home = ftp_home
        self.server_port = ftp_port

        super().__init__(**kwargs)

    def run(self):
        self._server = SimpleFTPServer(self.username, self.password,
                                       self.server_home, self.server_port)
        self._server.serve_forever()

这篇关于Python Errno 9 Mac OS X中的错误文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆