当前位置: 首页 > 知识库问答 >
问题:

Popen.communicate引发ValueError:'关闭文件上的I/O操作'

姬温文
2023-03-14

当我运行我的代码时,我收到以下错误。

    Uncaught exception <class 'ValueError'>: I/O operation on closed file.Traceback (most recent call last):
    File "/home/gidumah/miniconda/envs/ytune/lib/python3.7/runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "/home/gidumah/miniconda/envs/ytune/lib/python3.7/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/home/gidumah/ytopt/ytopt/ytopt/search/ambs.py", line 128, in <module>
        search.main()
      File "/home/gidumah/ytopt/ytopt/ytopt/search/ambs.py", line 105, in main
        results = list(self.evaluator.get_finished_evals())
      File "/home/gidumah/ytopt/ytopt/ytopt/evaluator/evaluate.py", line 200, in get_finished_evals
        y = future.result()
      File "/home/gidumah/ytopt/ytopt/ytopt/evaluator/subprocess_evaluator.py", line 41, in result
        stdout, stderr_data = self.proc.communicate()
      File "/home/gidumah/miniconda/envs/ytune/lib/python3.7/subprocess.py", line 951, in communicate
        stdout = self.stdout.read()
    ValueError: I/O operation on closed file.

我正在运行的代码是subprocess_evaluator.py,如下所示:

class PopenFuture:
    FAIL_RETURN_VALUE = Evaluator.FAIL_RETURN_VALUE

    def __init__(self, args, parse_fxn):
        self.proc = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT, encoding='utf-8')

        self._state = 'active'
        self._result = None
        self._parse = parse_fxn

    def _poll(self):
        if not self._state == 'active':
            return
        retcode = self.proc.poll()
        if retcode is None:
            self._state = 'active'
            stdout, stderr_data = self.proc.communicate()
            tmp_res = self._parse(stdout)
            if tmp_res != sys.float_info.max:
                self._result = tmp_res
        elif retcode == 0:
            self._state = 'done'
        else:
            self._state = 'failed'

    def result(self):
        if self._result is not None:
            return self._result
        self.proc.wait()
        stdout, stderr_data = self.proc.communicate()
        if self.done:
            self._result = self._parse(stdout)
        else:
            self._result = self.FAIL_RETURN_VALUE
            logger.error(f"Eval failed: {stdout}")
        ####
        # if stdout:
        #     print (stdout)#.split('\n')[:-2])#)[:-1])
        ####   
        return self._result

它说错误在第41行,给出为stdout,stder_data=self.proc.communicate()

沟通电话有什么问题吗?

共有1个答案

洪浩波
2023-03-14

根据留档:

popen.communicate(输入=无,超时=无)

进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到到达文件结尾。等待进程终止并设置returncode属性。可选的输入参数应该是发送到子进程的数据,如果没有数据发送到子进程,则为None。如果流以文本模式打开,输入必须是字符串。否则,它必须是字节。

请注意,它等待进程终止。因此Popen.communicate不能多次运行。Popen.communicate上下文中的错误意味着程序已经终止了进程并关闭了管道,并在第二次通信调用时引发了异常。

您似乎正在使用ytopt库的代码。请检查代码是否正确使用,请注意,它在几个不同的地方调用了communicate(),有时会传递ValueErrors,但有时不会。此外,请查看Thomas Wouters的问题解决方案:

如果你想使用通信,你必须要么重新启动循环中的进程,要么给它一个字符串,它是生成器的所有输入。如果你想进行流通信,一点一点地发送数据,那么你必须不使用通信。相反,你需要在读取p.stdout和p.stderr.的同时写入p.stdin。这样做很棘手,因为你无法分辨哪个输出是由哪个输入引起的,而且你很容易陷入死锁。有第三方库可以帮助你,比如Twisted。

如果您想以交互方式执行此操作,发送一些数据,然后在发送更多数据之前等待并处理结果,事情将变得更加困难。为此,您可能应该使用像pexpect这样的第三方库。

当然,如果你可以在循环中启动进程,那就容易多了:

cmd = ['intersectBed', '-a', 'stdin', '-b', bedfile]
for entry in my_entry_generator:
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output = p.communicate(input='\t'.join(entry) + '\n')[0]
    print output
 类似资料:
  • 问题内容: 这里,是一本字典,并且都是字符串。 当我尝试写入文件时,它报告错误: 问题答案: 正确缩进;您的陈述应在区块内: 在块外部,文件已关闭。

  • 我需要帮助,请我从2天前开始尝试解决此问题,但没有成功,我是python新手,请更改代码并解释: 这是它的代码和通过scapy的arp扫描程序。它从scapy扫描中获取结果,并将扫描结果(ip和macaddress)保存到linux机器中的txt文件中 然后运行一个外部python脚本,通过以下命令:os.system("pythondetect_doublepulsar_smb.py--file

  • 有人能解释一下我的代码有什么问题吗?我得到以下错误: 回溯(最后一次调用): 文件“C:\LineRep.py”,模块中的第15行: 对于文件2中的行: 值错误:对关闭的文件执行I/O操作 我的代码:

  • 我从Theano和Keras开始深入学习。但是,对于任何程序,我都必须加载数据集,而我无法加载任何数据集。 即使我运行这两行:- 我甚至用minst数据集尝试了上述方法。完全相同的错误。 我试着一个接一个地运行命令,第一次导入很顺利。在第二个命令中,它运行,python开始下载。然而,几秒钟后,它就断了。 这就是确切的错误:- (X_列,y_列),(X_测试,y_测试)=cifar10。load_

  • 我无法将单词打印到文件中。我的代码只是给我一个错误:

  • 代码从卡中刮取单个事件,但我一直收到以下错误: C:\Python27\python.exeC:/用户/詹姆斯/PycharmProjects/剪贴画/scrapy.py回溯(最近的调用最后):文件"C:/用户/詹姆斯/PycharmProjects/剪贴画/scrapy.py",第31行,在writer.writerow(c)值错误: I/O关闭文件的操作 我正在使用pyCharm。 退出代码为