Istnieje możliwość wielokrotnego tworzenia wielu procesów wsadowych w jednym pliku dziennika. Nic nie wiem o Pythonie, ale wyobrażam sobie, że koncepcje w tej odpowiedzi można zintegrować z Pythonem.
System Windows pozwala maksymalnie jednemu procesowi na otwarcie określonego pliku w celu uzyskania dostępu do zapisu w dowolnym momencie. Można to wykorzystać do zaimplementowania mechanizmu blokowania plików, który gwarantuje, że zdarzenia są szeregowane w wielu procesach. Zobacz https://stackoverflow.com/a/9048097/1012053 i http://www.dostips.com/forum/viewtopic.php?p=12454 dla niektórych przykładów.
Ponieważ wszystko, co próbujesz zrobić, to zapisać w dzienniku, możesz użyć samego pliku dziennika jako blokady. Operacja dziennika jest enkapsulowana w podprogramie, który próbuje otworzyć plik dziennika w trybie dołączania. Jeśli procedura się nie powiedzie, procedura powróci do poprzedniej procedury i spróbuje ponownie. Po pomyślnym otwarciu rejestr jest zapisywany, a następnie zamykany, a procedura powraca do wywołującego. Procedura rutynowa wykonuje wszystkie polecenia przekazywane do niej, a wszystko, co zapisano na standardowe wyjście w ramach procedury, jest przekierowywane do dziennika.
Oto skrypt testu wsadowego, który tworzy 5 procesów potomnych, z których każdy zapisuje do pliku dziennika 20 razy. Napisy są bezpiecznie przeplatane.
@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
Oto wynik, który pokazuje, że wszystkie 20 zapisy były udane dla każdego procesu
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
Można otworzyć wynikowy plik „myLog.log”, aby zobaczyć, w jaki sposób zapisy zostały bezpiecznie przeplatane. Ale wynik jest zbyt duży, aby opublikować go tutaj.
Łatwo udowodnić, że jednoczesne zapisy z wielu procesów mogą zakończyć się niepowodzeniem, modyfikując procedurę: log tak, aby nie była ponawiana po awarii.
:log command args...
>>%log% (
echo ***********************************************************
echo Proc %instance%: %date% %time%
%*
)
exit /b
Oto przykładowe wyniki po "łamanie" THE: log rutynowe
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
Po otwarciu pliku w systemie Windows (za pomocą CreateFile) można wybrać, czy inne procesy mogą czytać i/lub zapisywać do tego samego pliku, drugi proces musi określić zgodne flagi udziału ... – Anders
Wystarczająco sprawiedliwe. Mówiłem głównie o tym, jak partia Windows działa z przekierowaniem - nie mam tam żadnej opcji. Wiele procesów może czytać, nawet podczas pisania jednego procesu. (Nie jestem pewien, czy to zawsze jest bezpieczne). Ale nigdy więcej niż jeden proces otwarty na zapis. – dbenham
@dbenham: Bardzo dziękuję za to. To rozwiązuje kolejny duży problem, jaki mam. Może to również rozwiązać mój problem z logowaniem. Czy składnia '>> file (commands)' jest udokumentowana w dowolnym miejscu? – Omnifarious