如何在进程终止后等待,直到使用Python在Windows上解锁文件? 问题描述
我有一个单元测试,它调用一个外部程序并进行一些测试。之后,外部进程被终止,测试尝试清理外部程序创建的文件。但是,如果我在Windows 10上的如何在进程终止后等待,直到使用Python在Windows上解锁文件? 问题描述,python,subprocess,kill-process,Python,Subprocess,Kill Process,我有一个单元测试,它调用一个外部程序并进行一些测试。之后,外部进程被终止,测试尝试清理外部程序创建的文件。但是,如果我在Windows 10上的kill()命令之后直接调用unlink(),我会得到: PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'my.log' 如果在调用unlink()之前我time.sleep(4
kill()
命令之后直接调用unlink()
,我会得到:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'my.log'
如果在调用unlink()
之前我time.sleep(4)
,一切正常。4
是任意选择的,其他时间也可以
MCVE
这个MCVE有两个文件。一个只锁定日志文件的server.py
和一个调用服务器、杀死服务器并最终尝试删除日志文件的test\u client.py
测试客户端.py
import pathlib
import subprocess
import sys
import time
# Create test folder
server_path = pathlib.Path('.')
server_path.mkdir(exist_ok=True)
server_file = pathlib.Path('server.py').resolve()
# Start server in test folder
proc = subprocess.Popen([sys.executable, str(server_file)], cwd=server_path)
time.sleep(4)
# Kill server
proc.kill()
# Activate the following line to avoid the PermissionError: [WinError 32] ...
#time.sleep(4)
# Clean up
pathlib.Path('my.log').unlink()
import time
import logging
logging.basicConfig(
filename='my.log',
level=logging.DEBUG)
logging.info('I just started my work')
while True:
time.sleep(1)
server.py
import pathlib
import subprocess
import sys
import time
# Create test folder
server_path = pathlib.Path('.')
server_path.mkdir(exist_ok=True)
server_file = pathlib.Path('server.py').resolve()
# Start server in test folder
proc = subprocess.Popen([sys.executable, str(server_file)], cwd=server_path)
time.sleep(4)
# Kill server
proc.kill()
# Activate the following line to avoid the PermissionError: [WinError 32] ...
#time.sleep(4)
# Clean up
pathlib.Path('my.log').unlink()
import time
import logging
logging.basicConfig(
filename='my.log',
level=logging.DEBUG)
logging.info('I just started my work')
while True:
time.sleep(1)
问题:
- 有没有办法等待杀戮结束
- 如果代码不是特定于平台的,则奖励
- 正确的方法是
# Kill server
proc.kill()
# Activate the following line to avoid the PermissionError: [WinError 32] ...
proc.communicate()
# Clean up
pathlib.Path('my.log').unlink()
它这样做的原因需要一些文档
如中所述
Popen.kill()
杀死孩子。在Posix OSs上,函数将SIGKILL发送给子级。在Windows上kill()是terminate()的别名
Popen.terminate()
阻止孩子。在Posix OSs上,该方法将SIGTERM发送给子级。在Windows上,调用Win32 API函数TerminateProcess()来停止子进程
如前所述,在windows中,它正在调用Win32 API。然而,它明确指出
TerminateProcess是异步的;它启动终止并立即返回。如果需要确保进程已终止,请使用进程句柄调用WaitForSingleObject函数
因此,kill()
只是简单的“请求停止”。还没有停止。因此,您需要一种方法来“等待”流程结束
communicate()
也是为此目的而设计的,如文档中所述
与进程交互:向stdin发送数据。从stdout和stderr读取数据,直到到达文件末尾等待进程终止
正确的方法是
# Kill server
proc.kill()
# Activate the following line to avoid the PermissionError: [WinError 32] ...
proc.communicate()
# Clean up
pathlib.Path('my.log').unlink()
它这样做的原因需要一些文档
如中所述
Popen.kill()
杀死孩子。在Posix OSs上,函数将SIGKILL发送给子级。在Windows上kill()是terminate()的别名
Popen.terminate()
阻止孩子。在Posix OSs上,该方法将SIGTERM发送给子级。在Windows上,调用Win32 API函数TerminateProcess()来停止子进程
如前所述,在windows中,它正在调用Win32 API。然而,它明确指出
TerminateProcess是异步的;它启动终止并立即返回。如果需要确保进程已终止,请使用进程句柄调用WaitForSingleObject函数
因此,kill()
只是简单的“请求停止”。还没有停止。因此,您需要一种方法来“等待”流程结束
communicate()
也是为此目的而设计的,如文档中所述
与进程交互:向stdin发送数据。从stdout和stderr读取数据,直到到达文件末尾等待进程终止
它是用Win32.api的C编写的
kill()
没有如您所想的那样工作,请尝试添加一行proc.communicate()
,以便在调用unlink()
之前等待进程结束,然后应该可以工作。实际上,在proc.kill()
之后添加proc.communicate()
可以解决问题。是的,这就是我的意思proc.kill()
只要请求取消即可。你需要等待一些方法<代码>通信()用于此。看看我能不能找到一些文档…这是用Win32.api的C编写的kill()
没有如您所想的那样工作,请尝试添加一行proc.communicate()
,以便在调用unlink()
之前等待进程结束,然后应该可以工作。实际上,在proc.kill()
之后添加proc.communicate()
可以解决问题。是的,这就是我的意思proc.kill()
只要请求取消即可。你需要等待一些方法<代码>通信()用于此。看看我能不能找到这方面的文件。。。