避免在 Windows 批处理文件中同时调用
Avoid simultaneous call in Windows batch file
我有一个通用的 windows 构建批次(即 build.bat),它 运行 具有不同的参数。
start build.bat device1
start build.bat device2
start build.bat device3
但是在那批中有一个可执行文件在并行调用时崩溃。
是否可以使用 windows 内置函数,在另一个批次中已经 运行ning 时阻止此调用,并在另一个批次中完成时继续?
假设该批次的内容是
start delay 5
当多次调用批处理时,当另一个延迟当前 运行ning 时,延迟不得 运行。
这类似于信号量。
所以目标是拥有这样的东西
CheckAndWaitIfDelayIsRunning
start delay 5
提前致谢。
您可以使用 lock by file
.
批量构建信号量
:lock
2>nul (
> sema1.lock (
delay 5
REM The next line is for proper finishing the lock block
(call )
)
) || goto :lock
诀窍是,一次只允许一个进程写入 sema1.lock。
任何其他进程将失败并跳过内部块,|| goto :lock
将重试,直到可以写入 sema1.lock 文件。
这种技术的一个缺点是消耗 CPU,因为这个 信号量 并不是真正的等待,它更像是一个轮询信号量。
有关更多信息,请参阅 SO:How do you have shared log files under Windows?
根据回答我优化了两点:
- 控制台输出仍然可见且未重定向到文件中
- %errorlevel% 包含来自我的任务的错误
它使用第一次创建的文件夹作为锁。
Ping 用作等待时间并设置为 1000 毫秒。
它计算线程在获得执行其任务的许可之前等待的周期数。
脚本
set lockMyName="%TEMP%\my.lock"
set lockMyCounterMs=0
set lockMyTimeMs=1000
@echo [ INFO ] Getting my lock...
:lock_my
md %lockMyName% 2>nul
if "%errorlevel%" neq "0" (
set /a lockMyCounterMs+=%lockMyTimeMs%
:: commonly used timeout without waiting for input (must be invalid ip address)
ping 1.0.0.0 -n 1 -w %lockMyTimeMs% >nul
goto :lock_my
)
@echo [ INFO ] ... locked ^(waited %lockMyCounterMs% ms for lock^)
::do your task here
@echo [ INFO ] ...release my lock
rd /Q %lockMyName% 2>nul
我有一个通用的 windows 构建批次(即 build.bat),它 运行 具有不同的参数。
start build.bat device1
start build.bat device2
start build.bat device3
但是在那批中有一个可执行文件在并行调用时崩溃。
是否可以使用 windows 内置函数,在另一个批次中已经 运行ning 时阻止此调用,并在另一个批次中完成时继续?
假设该批次的内容是
start delay 5
当多次调用批处理时,当另一个延迟当前 运行ning 时,延迟不得 运行。
这类似于信号量。
所以目标是拥有这样的东西
CheckAndWaitIfDelayIsRunning
start delay 5
提前致谢。
您可以使用 lock by file
.
:lock
2>nul (
> sema1.lock (
delay 5
REM The next line is for proper finishing the lock block
(call )
)
) || goto :lock
诀窍是,一次只允许一个进程写入 sema1.lock。
任何其他进程将失败并跳过内部块,|| goto :lock
将重试,直到可以写入 sema1.lock 文件。
这种技术的一个缺点是消耗 CPU,因为这个 信号量 并不是真正的等待,它更像是一个轮询信号量。
有关更多信息,请参阅 SO:How do you have shared log files under Windows?
根据回答我优化了两点:
- 控制台输出仍然可见且未重定向到文件中
- %errorlevel% 包含来自我的任务的错误
它使用第一次创建的文件夹作为锁。
Ping 用作等待时间并设置为 1000 毫秒。
它计算线程在获得执行其任务的许可之前等待的周期数。
脚本
set lockMyName="%TEMP%\my.lock"
set lockMyCounterMs=0
set lockMyTimeMs=1000
@echo [ INFO ] Getting my lock...
:lock_my
md %lockMyName% 2>nul
if "%errorlevel%" neq "0" (
set /a lockMyCounterMs+=%lockMyTimeMs%
:: commonly used timeout without waiting for input (must be invalid ip address)
ping 1.0.0.0 -n 1 -w %lockMyTimeMs% >nul
goto :lock_my
)
@echo [ INFO ] ... locked ^(waited %lockMyCounterMs% ms for lock^)
::do your task here
@echo [ INFO ] ...release my lock
rd /Q %lockMyName% 2>nul