任务完成,退出时自动清理 Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x0000014A2C765440> Traceback (most recent call last): File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 125, in __del__ _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 78, in __repr__ info.append(f'stdout={stdout.pipe}') Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x0000014A2C765440> Traceback (most recent call last): File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 125, in __del__ _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 78, in __repr__ info.append(f'stdout={stdout.pipe}') _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 78, in __repr__ info.append(f'stdout={stdout.pipe}') File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\base_subprocess.py", line 78, in __repr__ info.append(f'stdout={stdout.pipe}') info.append(f'stdout={stdout.pipe}') ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\proactor_events.py", line 80, in __repr__ info.append(f'fd={self._sock.fileno()}') ^^^^^^^^^^^^^^^^^^^ File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\windows_utils.py", line 102, in fileno raise ValueError("I/O operation on closed pipe") ValueError: I/O operation on closed pipe Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000014A2C766B60> Traceback (most recent call last): File "C:\Users\10263414\.conda\envs\mcp\Lib\asyncio\proactor_events.py", line 116, in
时间: 2025-07-01 20:55:25 浏览: 12
在使用 Python 的 `asyncio` 模块处理异步子进程时,可能会遇到 `ResourceWarning` 警告,提示 `unclosed transport`。这通常是因为没有正确关闭子进程的传输(transport)对象导致的。
### 原因分析
`BaseSubprocessTransport` 是 `asyncio` 中用于管理子进程通信的核心类之一。当创建一个子进程时,会返回一个与之关联的 `transport` 对象,该对象负责管理子进程的标准输入、输出和错误流。如果这些流没有被显式关闭,或者子进程没有被正确等待(通过 `await process.wait()`),则可能导致资源泄漏,并触发 `ResourceWarning` 警告。
具体来说,当 `BaseSubprocessTransport` 实例被垃圾回收器回收时,其 `__del__` 方法会被调用。如果此时传输尚未关闭,则会发出 `unclosed transport` 的警告[^1]。
### 解决方案
为了避免此类警告并确保资源得到正确释放,可以采取以下措施:
#### 1. 显式关闭子进程的流
在使用 `asyncio.create_subprocess_exec` 或 `asyncio.create_subprocess_shell` 创建子进程后,应该显式地关闭所有未使用的流。例如,如果你只关心子进程的标准输出,那么可以关闭标准输入和标准错误:
```python
import asyncio
async def run():
process = await asyncio.create_subprocess_exec(
'echo', 'Hello World',
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
# 关闭不需要的流
if process.stdin:
process.stdin.close()
if process.stderr:
process.stderr.close()
stdout, _ = await process.communicate()
print(stdout.decode())
asyncio.run(run())
```
#### 2. 等待子进程完成
确保在退出之前等待子进程完成。可以通过调用 `await process.wait()` 来实现这一点。这样可以保证子进程的状态被正确更新,并且相关的资源能够被及时释放:
```python
import asyncio
async def run():
process = await asyncio.create_subprocess_exec(
'sleep', '5'
)
await process.wait() # 硉保子进程结束后再继续执行
asyncio.run(run())
```
#### 3. 使用 `communicate()` 方法
如果你需要读取子进程的输出,推荐使用 `process.communicate()` 方法,它会自动处理输入/输出流,并等待子进程结束:
```python
import asyncio
async def run():
process = await asyncio.create_subprocess_exec(
'echo', 'Hello World',
stdout=asyncio.subprocess.PIPE
)
stdout, _ = await process.communicate()
print(stdout.decode())
asyncio.run(run())
```
#### 4. 在 `finally` 块中清理资源
为了进一步确保资源不会泄露,可以在 `finally` 块中显式关闭流或等待子进程结束:
```python
import asyncio
async def run():
process = await asyncio.create_subprocess_exec(
'echo', 'Hello World',
stdout=asyncio.subprocess.PIPE
)
try:
stdout, _ = await process.communicate()
print(stdout.decode())
finally:
if process.stdin:
process.stdin.close()
if process.stdout:
process.stdout.close()
if process.stderr:
process.stderr.close()
asyncio.run(run())
```
### 总结
`ResourceWarning: unclosed transport` 通常是由于未能正确关闭子进程的流或未等待子进程完成所引起的。通过显式关闭流、等待子进程结束或使用 `communicate()` 方法,可以有效避免此类问题的发生。此外,在异常处理中加入资源清理逻辑也是良好的编程习惯,有助于提高程序的健壮性和可靠性。
阅读全文
相关推荐





