您可以使用锁定的文件作为简单的信号量来串行化事件。当您在批处理文件中将stdout重定向到文件时,它会在该文件上建立一个独占写锁。没有其他进程可以打开同一个文件以进行写访问。无论如何结束(干净退出、CTRL-C、异常失败等),锁都会自动释放。
批处理文件可以尝试将9重定向到锁定文件,如果失败,就会循环回来直到成功。symstore命令仅在锁定期间运行。使用非标准文件句柄(流?)以使锁定不会干扰stdin、stdout或stderr处理。
所以您只需要确保永远不要直接调用symstore。而是始终通过批处理脚本调用它。类似以下内容(serializeSymstore.bat):
@echo off
setlocal
:loop
:: Save stderr definition and redirect stderr to nul
:: to hide possible redirection error when establishing lock.
8>&2 2>nul (
%= Attempt to establish the lock and restore stderr =%
9>"\\centralServer\somePath\symstore.lock" 2>&8 (
%= If got here then lock is established throughout all commands =%
%= in this set of parentheses. =%
%= Execute your command =%
symstore %*
%= Save the return code =%
call set "rtnCd=%%errorlevel%%"
%= The next command is a very fast way to clear the ERRORLEVEL. =%
%= We don't want symstore failure to trigger a loop. =%
(call )
)
) || (
%= If entered here then failed to establish lock. =%
%= Wait 1 second and then loop back to retry. =%
%= Replace with PING delay if TIMEOUT not universally available. =%
timeout 1 /nobreak >nul
goto loop
)
:: Exit with appropriate return code
exit /b %rtnCd%
没有注释,代码就变成了一小段。
@echo off
setlocal
:loop
8>&2 2>nul (
9>"\\centralServer\somePath\symstore.lock" 2>&8 (
symstore %*
call set "rtnCd=%%errorlevel%%"
(call )
)
) || (
timeout 1 /nobreak >nul
goto loop
)
exit /b %rtnCd%
我发现这种原始且简单的策略在许多项目中非常有效。我必须承认,我没有在远程机器上测试锁定和释放特性。但我相信只要所有机器都是Windows,它应该是可靠的。
我知道唯一的缺点是没有FIFO队列。如果收到多个重叠的请求,那么哪个进程可以接下来运行就是随机的。但进程将被序列化。
编辑:我在编辑之前阅读了splattered bits的原始答案。他质疑文件锁定在远程机器上是否可靠。我做了一些快速的Google搜索,似乎UNC路径上的文件锁定存在一些问题。如果遇到问题,您可能更好地将其重定向到映射驱动器字母上的文件,而不是直接通过UNC路径访问。这全都是理论 - 我没有进行任何测试。请务必在承诺使用此解决方案之前进行充分的测试。请注意,PUSHD是一个方便的方法,可以临时为UNC路径分配驱动器号,而无需知道可用的驱动器号。POPD将取消映射驱动器的分配。
symstore
吗?还是需要在不同计算机上运行symstore
,并管理位于中央计算机上的符号存储? - Aaron Jensen