Можно иметь несколько пакетных процессов для безопасной записи в один файл журнала. Я ничего не знаю о Python, но я думаю, что концепции в этом ответе могут быть интегрированы с Python.
Windows позволяет не более одного процесса иметь определенный файл, открытый для доступа на запись в любой момент времени. Это может быть использовано для реализации механизма блокировки на основе файлов, который гарантирует сериализацию событий между несколькими процессами. См. https://stackoverflow.com/a/9048097/1012053 и http://www.dostips.com/forum/viewtopic.php?p=12454 для некоторых примеров.
Поскольку все, что вы пытаетесь сделать, это записывать в журнал, вы можете использовать сам файл журнала в качестве блокировки. Операция журнала инкапсулируется в подпрограмму, которая пытается открыть файл журнала в режиме добавления. Если открытие не удается, процедура возвращается назад и пытается снова. После успешного открытия журнал записывается, а затем закрывается, и процедура возвращается к вызывающей стороне. Подпрограмма выполняет любую команду, переданную ей, и все, что записано на стандартный вывод в подпрограмме, перенаправляется в журнал.
Вот тестовый пакетный скрипт, который создает 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