我有几个不同的进程,我希望他们都登录到同一个文件.这些进程在
Windows 7系统上运行.一些是python脚本,另一些是cmd批处理文件.
在Unix下,你只需让所有人以附加模式打开文件并写下来.只要每个进程在单个消息中写入的PIPE_BUF字节少于PIPE_BUF字节,就可以保证每个写入调用不与任何其他写入调用交错.
有没有办法在Windows下实现这一目标?天真的类Unix方法失败了,因为Windows不喜欢默认情况下一次打开文件的多个进程.
可以将多个批处理过程安全地写入单个日志文件.我对
Python一无所知,但我想这个答案中的概念可以与Python集成.
Windows允许最多一个进程在任何时间点打开特定文件以进行写访问.这可用于实现基于文件的锁定机制,以确保事件在多个进程中被序列化.有关示例,请参见https://stackoverflow.com/a/9048097/1012053和http://www.dostips.com/forum/viewtopic.php?p=12454.
由于您要做的只是写入日志,因此您可以将日志文件本身用作锁定.日志操作封装在子例程中,该子例程尝试以追加模式打开日志文件.如果打开失败,则例程循环返回并再次尝试.一旦打开成功,将写入日志然后关闭,并且例程返回给调用者.例程执行传递给它的任何命令,并且在例程中写入stdout的任何内容都会重定向到日志.
这是一个测试批处理脚本,它创建5个子进程,每个进程写入日志文件20次.写入是安全交错的.
@echo off setlocal if "%~1" neq "" goto :test :: Initialize set log="myLog.log" 2>nul del %log% 2>nul del "test*.marker" set procCount=5 set testCount=10 :: Launch %procCount% processes that write to the same log for /l %%n in (1 1 %procCount%) do start "" /b "%~f0" %%n :wait for child processes to finish 2>nul dir /b "test*.marker" | find /c "test" | >nul findstr /x "%procCount%" || goto :wait :: Verify log results for /l %%n in (1 1 %procCount%) do ( <nul set /p "=Proc %%n log count = " find /c "Proc %%n: " <%log% ) :: Cleanup del "test*.marker" exit /b ============================================================================== :: code below is the process that writes to the log file :test set instance=%1 for /l %%n in (1 1 %testCount%) do ( call :log echo Proc %instance% says hello! call :log dir "%~f0" ) echo done >"test%1.marker" exit :log command args... 2>nul ( >>%log% ( echo *********************************************************** echo Proc %instance%: %date% %time% %* (call ) %= This odd Syntax guarantees the inner block ends with success =% %= We only want to loop back and try again if redirection Failed =% ) ) || goto :log exit /b
以下是输出,表明每个进程的所有20次写入都是成功的
Proc 1 log count = 20 Proc 2 log count = 20 Proc 3 log count = 20 Proc 4 log count = 20 Proc 5 log count = 20
您可以打开生成的“myLog.log”文件,以查看写入是如何安全交错的.但输出太大,无法在此发布.
通过修改:log例程以便在失败时不重试,很容易证明来自多个进程的同时写入可能会失败.
:log command args... >>%log% ( echo *********************************************************** echo Proc %instance%: %date% %time% %* ) exit /b
以下是“破解”:log例程后的一些示例结果
The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. The process cannot access the file because it is being used by another process. Proc 1 log count = 12 Proc 2 log count = 16 Proc 3 log count = 13 Proc 4 log count = 18 Proc 5 log count = 14