bash sem - 根据 id 限制 sem 命令的数量
bash sem - limit number of sem commands based on id
我的脚本中有一个场景,我同时 运行 宁几个 sem
命令。我在这里 运行同时执行 1000 个 sem 命令。
文件名:sem_script.sh
#/usr/bin/bash
fun() {
#dosomething with the $param
echo
}
export -f fun
sem --id someid --fg fun $param
我使用sem
的原因是我希望fun
到运行一个接一个
所以如果我这样做
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
...
..
... more than 1000 times
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
然后会输出
test
test
test
test
test
test
...
..
... more than 1000 times
test
test
test
但这里的问题是它一次打开 1000 个 sem 命令,它们在队列中一个接一个地等待 运行。这会阻塞我的 cpu 和我的 ram 以及所有东西。
所以我决定不想让超过 4 个 sem 命令在此处 id
的特定 someid
队列中
想要的如下:
#/usr/bin/bash
fun() {
#dosomething with the $param
echo
}
export -f fun
num_sem_instances = get how many sem instances are running with id someid
if(num_sem_instances < 4), then {
#allow to create a sem instance
sem --id someid --fg fun $param
}
else {
#dont create an sem instance
echo "already have 4 instances of sem with id=someid"
# rerun the script again and try your luck
sh sem_script.sh "test" &
}
因为在bash中,当脚本同时执行时,上述逻辑可能不起作用。当脚本有一些时间延迟时它会起作用
比上面的逻辑更好,我强烈希望 sem
命令中有一个选项只允许它有 4
个 id someid
运行 的实例任何时候在我的电脑上 ning 和休息它都不允许 运行.
我怀疑这是因为你需要在每次执行之间添加一个延迟。操作系统需要能够 运行 一个命令,然后分配一些 CPU 时间给另一个用户或进程,然后回来 运行 你的下一个命令。
#!/bin/sh -x
count=1
next() {
[[ "${count}" -lt 1000 ]] && main
exit 0
}
main() {
sem_script.sh "test"
sleep 0.5
count=$(($count+1))
next
}
next
这非常快速和肮脏,但它应该有效。它创建一个计数器,最高可达 1,000,并且 运行 将脚本延迟 0.5 秒,就在每次递增计数器之前。一旦计数器达到 1,000,脚本就会退出。
当 sem 运行ning 时,它会添加一个 pid 文件到 ~/.parallel/semaphones/id-someid/,所以你应该可以在这里计算有 pid 的文件。
我只是在 cli 中 运行 sem --id someid -j2 sleep 10
两次并列出了该目录的内容:
[user@laptop ~]$ ls -lah .parallel/semaphores/id-someid/
total 8.0K
drwxrwxr-x. 2 user user 4.0K Jul 9 09:47 .
drwxrwxr-x. 3 user user 4.0K Jul 9 09:47 ..
-rw-rw-r--. 3 user user 0 Jul 9 09:47 19428@laptop.wks
-rw-rw-r--. 3 user user 0 Jul 9 09:47 19449@laptop.wks
-rw-rw-r--. 3 user user 0 Jul 9 09:47 id-someid
所以在你的脚本中,我会把
num_sem_instances = $(find ~/.parallel/semaphores/id-${YOURID}/ -type f 2> /dev/null | awk -F/ '{print $NF}' | grep ^[0-9] | wc -l)
编辑:
如果一次只有一个 sem
可以 运行(即 -j1
),并且一次只能排队四个命令实例,则可以将 sem 包装在另一个并行进程,仅在计算排队命令后才将任务排队:
fun () { echo ; sleep 1 }
runfun () {
numqueued=$(find ~/.parallel/semaphores/id-queued/ -type f 2> /dev/null | awk -F/ '{print $NF}' | grep ^[0-9] | wc -l)
if [ $numqueued < 4 ]; then
parallel -j4 --bg --id queued sem --id funid --fg fun
else
echo "too much fun right now"
fi
}
export -f fun
runfun
我的脚本中有一个场景,我同时 运行 宁几个 sem
命令。我在这里 运行同时执行 1000 个 sem 命令。
文件名:sem_script.sh
#/usr/bin/bash
fun() {
#dosomething with the $param
echo
}
export -f fun
sem --id someid --fg fun $param
我使用sem
的原因是我希望fun
到运行一个接一个
所以如果我这样做
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
...
..
... more than 1000 times
sh sem_script.sh "test" &
sh sem_script.sh "test" &
sh sem_script.sh "test" &
然后会输出
test
test
test
test
test
test
...
..
... more than 1000 times
test
test
test
但这里的问题是它一次打开 1000 个 sem 命令,它们在队列中一个接一个地等待 运行。这会阻塞我的 cpu 和我的 ram 以及所有东西。
所以我决定不想让超过 4 个 sem 命令在此处 id
的特定 someid
想要的如下:
#/usr/bin/bash
fun() {
#dosomething with the $param
echo
}
export -f fun
num_sem_instances = get how many sem instances are running with id someid
if(num_sem_instances < 4), then {
#allow to create a sem instance
sem --id someid --fg fun $param
}
else {
#dont create an sem instance
echo "already have 4 instances of sem with id=someid"
# rerun the script again and try your luck
sh sem_script.sh "test" &
}
因为在bash中,当脚本同时执行时,上述逻辑可能不起作用。当脚本有一些时间延迟时它会起作用
比上面的逻辑更好,我强烈希望 sem
命令中有一个选项只允许它有 4
个 id someid
运行 的实例任何时候在我的电脑上 ning 和休息它都不允许 运行.
我怀疑这是因为你需要在每次执行之间添加一个延迟。操作系统需要能够 运行 一个命令,然后分配一些 CPU 时间给另一个用户或进程,然后回来 运行 你的下一个命令。
#!/bin/sh -x
count=1
next() {
[[ "${count}" -lt 1000 ]] && main
exit 0
}
main() {
sem_script.sh "test"
sleep 0.5
count=$(($count+1))
next
}
next
这非常快速和肮脏,但它应该有效。它创建一个计数器,最高可达 1,000,并且 运行 将脚本延迟 0.5 秒,就在每次递增计数器之前。一旦计数器达到 1,000,脚本就会退出。
当 sem 运行ning 时,它会添加一个 pid 文件到 ~/.parallel/semaphones/id-someid/,所以你应该可以在这里计算有 pid 的文件。
我只是在 cli 中 运行 sem --id someid -j2 sleep 10
两次并列出了该目录的内容:
[user@laptop ~]$ ls -lah .parallel/semaphores/id-someid/
total 8.0K
drwxrwxr-x. 2 user user 4.0K Jul 9 09:47 .
drwxrwxr-x. 3 user user 4.0K Jul 9 09:47 ..
-rw-rw-r--. 3 user user 0 Jul 9 09:47 19428@laptop.wks
-rw-rw-r--. 3 user user 0 Jul 9 09:47 19449@laptop.wks
-rw-rw-r--. 3 user user 0 Jul 9 09:47 id-someid
所以在你的脚本中,我会把
num_sem_instances = $(find ~/.parallel/semaphores/id-${YOURID}/ -type f 2> /dev/null | awk -F/ '{print $NF}' | grep ^[0-9] | wc -l)
编辑:
如果一次只有一个 sem
可以 运行(即 -j1
),并且一次只能排队四个命令实例,则可以将 sem 包装在另一个并行进程,仅在计算排队命令后才将任务排队:
fun () { echo ; sleep 1 }
runfun () {
numqueued=$(find ~/.parallel/semaphores/id-queued/ -type f 2> /dev/null | awk -F/ '{print $NF}' | grep ^[0-9] | wc -l)
if [ $numqueued < 4 ]; then
parallel -j4 --bg --id queued sem --id funid --fg fun
else
echo "too much fun right now"
fi
}
export -f fun
runfun