为了账号安全,请及时绑定邮箱和手机立即绑定

Python子流程:他们如何/何时关闭文件?

Python子流程:他们如何/何时关闭文件?

一只甜甜圈 2022-09-20 15:47:17
我想知道为什么子进程使这么多文件保持打开状态。我有一个例子,其中某些文件似乎永远保持打开状态(在子进程完成后,甚至在程序崩溃之后)。请考虑以下代码:import aiofilesimport tempfileasync def main():    return [await fds_test(i) for i in range(2000)]async def fds_test(index):    print(f"Writing {index}")    handle, temp_filename = tempfile.mkstemp(suffix='.dat', text=True)    async with aiofiles.open(temp_filename, mode='w') as fp:        await fp.write('stuff')        await fp.write('other stuff')        await fp.write('EOF\n')    print(f"Reading {index}")    bash_cmd = 'cat {}'.format(temp_filename)    process = await asyncio.create_subprocess_exec(*bash_cmd.split(), stdout=asyncio.subprocess.DEVNULL, close_fds=True)    await process.wait()    print(f"Process terminated {index}")if __name__ == "__main__":    import asyncio    asyncio.run(main())这将一个接一个地生成进程(按顺序)。我希望同时打开的文件数量也是一个。但事实并非如此,在某些时候我得到以下错误:/Users/cglacet/.pyenv/versions/3.8.0/lib/python3.8/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)   1410             # Data format: "exception name:hex errno:description"   1411             # Pickle is not used; it is complex and involves memory allocation.-> 1412             errpipe_read, errpipe_write = os.pipe()   1413             # errpipe_write must not be in the standard io 0, 1, or 2 fd range.   1414             low_fds_to_close = []OSError: [Errno 24] Too many open files我尝试在没有该选项的情况下运行相同的代码,但它仍然崩溃。这个答案表明,这可能是问题的根源,错误也指向线 。但这似乎不是问题所在(在没有该选项的情况下运行会产生相同的错误)。stdout=asyncio.subprocess.DEVNULLerrpipe_read, errpipe_write = os.pipe()
查看完整描述

1 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

问题不是来自此代码中的问题是 tempfile.mkstemp() 实际上打开了该文件:create_subprocess_exec

mkstemp() 返回一个元组,其中包含一个打开文件的操作系统级句柄(由 os.open()返回) ...

我以为它只会创建文件。为了解决我的问题,我只是在 中添加了一个调用。这消除了错误,但有点奇怪(打开文件两次)。所以我把它改写为:os.close(handle)

import aiofiles

import tempfile

import uuid



async def main():

    await asyncio.gather(*[fds_test(i) for i in range(10)])


async def fds_test(index):

    dir_name = tempfile.gettempdir()

    file_id = f"{tempfile.gettempprefix()}{uuid.uuid4()}"

    temp_filename = f"{dir_name}/{file_id}.dat"


    async with aiofiles.open(temp_filename, mode='w') as fp:

        await fp.write('stuff')


    bash_cmd = 'cat {}'.format(temp_filename)

    process = await asyncio.create_subprocess_exec(*bash_cmd.split(), close_fds=True)

    await process.wait()



if __name__ == "__main__":

    import asyncio

    asyncio.run(main())

现在我想知道为什么错误是由而不是引起的,也许是因为它子进程打开了更多的文件,以至于它不太可能使临时文件创建成为打破限制的原因......subprocesstempfile.mkstemp


查看完整回答
反对 回复 2022-09-20
  • 1 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信