首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过Powershell或批处理序列化符号存储的执行

通过Powershell或批处理序列化符号存储的执行
EN

Stack Overflow用户
提问于 2013-08-01 18:56:30
回答 3查看 1.4K关注 0票数 3

我们正在努力将一个步骤集成到我们的持续集成(CI)服务器(CruiseControl.NET)中。我们希望将构建过程中生成的调试符号*.pdb注册到Microsoft符号服务器中。正如微软实现的那样,符号服务器是Visual用来为C++/C#可执行文件查找*.pdb调试符号的目录结构。微软提供了一个命令symstore,它在一个目录中接受调试符号,并酌情填充中央符号存储目录。

问题是symstore显式地声明并发运行是不安全的。

我们可以尝试哪些方法或策略来禁止通过批处理或Powershell脚本并发执行symstore命令?

我们在方法上是灵活的,但是由于我们在Windows平台上运行,批处理和Powershell是首选的解决方案。

Clarification:

对于我们的用例,symstore需要在两个不同的CI服务器上运行,这将在一个普通的网络驱动器上保存符号。

资源:

符号商店::http://msdn.microsoft.com/en-us/library/windows/desktop/ms681417(v=vs.85).aspx

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-01 22:14:11

您可以使用锁定的文件作为一个简单的信号量来序列化事件。当您将stdout重定向到批处理文件中的文件时,它将在该文件上建立独占写入锁。任何其他进程都不能打开相同的文件进行写访问。该锁将在进程结束时自动释放,无论它如何结束(清除退出、CTRL-C、异常失败等)。

批处理文件可以尝试将9重定向到锁文件,如果失败,则返回直到成功。符号存储命令只有在锁就位时才能运行。非标准文件句柄(流?)用于使锁不干扰stdin、stdout或stderr处理。

所以你只需要确保你永远不要直接打给符号商店。相反,您总是通过批处理脚本调用它。类似于以下内容(serializeSymstore.bat):

代码语言:javascript
复制
@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%

如果没有注释,它就会变成一小部分代码。

代码语言:javascript
复制
@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队列。如果接收到多个重叠请求,那么抽签的随机运气将决定下一步的进程。但是进程将被序列化。

编辑:

在编辑之前,我读过飞溅比特的原始答案。他质疑远程机器上的文件锁定是否可靠。我做了一些快速谷歌搜索,似乎确实存在一些问题,文件锁定在UNC路径。如果遇到问题,您可能会更幸运地重定向到映射驱动器号上的文件,而不是直接通过UNC路径。这都是理论-我没有做过测试。在承诺使用此解决方案之前,请确保进行充分的测试。请注意,PUSHD是一种方便的方法,可以暂时将驱动器字母分配到UNC路径,而不知道有哪些驱动器字母可用。POPD将解除驱动器分配的映射。

票数 6
EN

Stack Overflow用户

发布于 2013-08-01 19:11:48

为了锁定对网络驱动器的访问权限,您将需要一个与您的CI服务对话的第三方。然后这个第三方将处理对网络驱动器的访问。这一第三方可能是:

  • MSMQ
  • 数据库表中的行
  • 在运行symstore的符号服务器上使用WCF服务,您的CCNet会与它建立对话以触发symstore
  • 具有可以远程触发的项目/作业的符号服务器上的CCNet
  • 可以从CI服务器远程触发的符号服务器上的计划作业。
票数 0
EN

Stack Overflow用户

发布于 2013-08-01 19:05:56

使用共享目录中的文件作为信号量,以避免并发执行。

代码语言:javascript
复制
:checkfile
if exist %cidir%\sem.txt goto :wait10secs
echo gotit! >%cidir%\sem.txt
doit
del %cidir%\sem.txt
goto :eof
:wait10secs
ing 192.0.2.2 -n 1 -w 10000 > nul
goto :checkfile

准备调试所有奇怪的方式,您的批处理可能失败和所有恶劣的赛车条件。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18002294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档