避免在Windows批处理文件中同时调用
我有一个通用的windows构建批处理(即build.bat),它以不同的参数在Parralel中运行避免在Windows批处理文件中同时调用,windows,batch-file,semaphore,Windows,Batch File,Semaphore,我有一个通用的windows构建批处理(即build.bat),它以不同的参数在Parralel中运行 start build.bat device1 start build.bat device2 start build.bat device3 但在该批处理中,有一个可执行文件在Parralel中被调用时崩溃 使用windows内置函数,是否可以在调用已在另一批中运行时阻止该调用,并在该批中完成后继续 假设该批次的内容是 start delay 5 当批处理多次被调用时,当另一个延迟正在运
start build.bat device1
start build.bat device2
start build.bat device3
但在该批处理中,有一个可执行文件在Parralel中被调用时崩溃
使用windows内置函数,是否可以在调用已在另一批中运行时阻止该调用,并在该批中完成后继续
假设该批次的内容是
start delay 5
当批处理多次被调用时,当另一个延迟正在运行时,该延迟不能运行
这与信号量类似
所以我们的目标是拥有这样的东西
CheckAndWaitIfDelayIsRunning
start delay 5
提前感谢。您可以使用
文件锁定来批量构建信号量
: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,因为这个信号量不是真正的等待,它更像是一个轮询信号量
有关更多信息,请参见您可以通过使用文件锁定来批量构建信号量
: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,因为这个信号量不是真正的等待,它更像是一个轮询信号量
更多信息请参见根据答案,我优化了两件事:
- 控制台输出仍然可见,并且没有重定向到文件中
- %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
根据答案,我优化了两件事:
- 控制台输出仍然可见,并且没有重定向到文件中
- %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
插入
timeout 1
命令以降低轮询率如何?这行得通吗?是的,这行得通,但会减慢程序的反应,因为semaLock在等待另一个线程的释放时平均会等待0.5秒。插入timeout 1
命令以降低轮询率怎么样?这行得通吗?是的,行得通,但会减慢程序的反应,因为semaLock在等待另一个版本发布时平均会等待0.5秒thread@AdrianoRepetti:start
命令没有任何等待另一进程终止的选项…@Aacini true,我只是重新阅读了这个问题,但我错过了要点(等待另一个进程,而不是第二批进程本身终止)@AdrianoRepetti:start命令没有任何选项可以等待另一个进程的终止…@Aacini true,我只是重新阅读了这个问题,我错过了要点(等待另一个进程,而不是第二批本身终止)