我的脚本中有一个场景,在这个场景中,我同时运行几个sem命令。在这里,我同时运行1000个sem命令。
文件名:sem_script.sh
#/usr/bin/bash
fun() {
#dosomething with the $param
echo $1
}
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和内存,所有的东西都堵塞了。
因此,我决定不允许超过4个sem命令排在特定id someid的队列中。
所需要的如下:
#/usr/bin/bash
fun() {
#dosomething with the $param
echo $1
}
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命令中有一个选项,它只允许在我的pc上的任何时间点运行id someid的4实例,而rest不允许运行。
发布于 2020-07-09 13:50:54
当一个sem运行时,它会将一个pidfile添加到~/.pidfile/信号量/id-someid/中,因此您应该能够在这里对具有pids的文件进行计数。
我只是在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 $1; 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 $1
else
echo "too much fun right now"
fi
}
export -f fun
runfun $1发布于 2020-06-23 18:45:36
我怀疑这是因为您需要在每次执行之间添加一个延迟。操作系统需要能够运行命令,然后为其他用户或进程分配一些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秒的延迟运行脚本。一旦计数器在1000,000,脚本退出。
https://stackoverflow.com/questions/62538776
复制相似问题