【问题标题】:bash : how to wait some time to avoid simultaneous run of a script?bash:如何等待一段时间以避免同时运行脚本?
【发布时间】:2023-12-18 00:42:01
【问题描述】:

我的问题:

每天晚上,我的 crontab 都会在 CentOS 6.5 下使用 PBS 的超级计算机上启动几个夜间测试。启动时,作业在队列中等待。当调度程序允许运行时,我的工作就开始了。这比调度程序同时启动所有作业更常见(即使我的 crontab 在分开的时刻启动它们)。

我无法修改工作的主要部分(但我可以在之前添加内容)。每个作业都从更新一个通用 SVN 存储库开始。但是,当作业同时开始时,由于同一存储库上的并发更新,我遇到了错误。我想避免这种情况。

我的期望:

当由调度程序启动时,作业可能会在启动前等待几秒钟。一个解决方案可能是在开始之前等待一个随机时间,但是随着我并行执行的测试数量的增加,拥有相同随机时间的风险会快速增长。如果我通过选择一个大的随机数来降低这种风险,我必须等待太久(锁定超级计算机上未使用的资源)。

我想可以以多线程安全的方式为每个作业存储“我现在启动,其他人必须等待 1 分钟”的信息,但我没有'不知道怎么做。我想象的是一种互斥锁,但只会导致延迟而不是等待结束的锁。

首选没有 MPI 的解决方案。

当然,我愿意接受其他解决方案。欢迎任何帮助。

【问题讨论】:

标签: bash svn concurrency mutex pbs


【解决方案1】:

从尝试首先获取锁定文件的排他锁的包装器中调用您的脚本。例如

{
    flock -s 200
    # your script/code here
} 200> /var/lock/myscript

锁定文件的名称并不重要,只要您有打开它的写权限即可。当这个包装器运行时,它首先会尝试获得/var/lock/myscript 的排他锁。如果另一个脚本已经拥有锁,它将阻塞,直到锁可用。

请注意,没有任意的等待时间;每个脚本将按照它们第一次尝试获取锁的顺序尽快运行。这意味着您也可以同时开始工作;操作系统将管理对锁的访问和排序。

【讨论】:

  • 如果我很好理解,这将在所有脚本期间锁定。我只想在脚本执行的前几秒锁定。
  • 嗯。也许使用锁来序列化对sleep 1的调用?然后每个作业名义上休眠 1 秒,但必须等待任何先前排队的作业完成它们的“1 秒”休眠。实际上,nth 作业会休眠 n 秒,而您无需为每个作业手动分配不同的休眠时间。
【解决方案2】:

这是使用GNU parallel的解决方案

一开始使用这个工具可能看起来有点违反直觉,但是如果将一次运行的最大作业数设置为 1,它可以模拟一个作业队列,依次运行多个作业而没有任何重叠.

你可以通过这个例子来观察这个命令想要的效果

seq 1 5 | parallel -j1 -k 'echo {}; sleep 1'

-j1 将一次运行的最大作业数设置为 1,而-k 保留顺序。

要将此应用于您的原始问题,我们可以创建一个文件,使其包含逐行的脚本文件列表。然后我们可以将该文件的内容通过管道传递给parallel,以使多个脚本按顺序运行。

cat file | parallel -j1 -k bash {}

【讨论】:

    最近更新 更多