首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bash sem -基于id的sem命令的限制数

bash sem -基于id的sem命令的限制数
EN

Stack Overflow用户
提问于 2020-06-23 15:51:19
回答 2查看 726关注 0票数 0

我的脚本中有一个场景,在这个场景中,我同时运行几个sem命令。在这里,我同时运行1000个sem命令。

文件名:sem_script.sh

代码语言:javascript
复制
#/usr/bin/bash
fun() {
  #dosomething with the $param
  echo $1
}
export -f fun

sem --id someid --fg fun $param

我使用sem的原因是我希望fun一个接一个地运行

所以如果我做了

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

然后它会输出

代码语言:javascript
复制
test
test
test
test
test
test
...
..
... more than 1000 times
test
test
test

但是这里的问题是,它一次打开1000个sem命令,它们在队列中等待一个接一个地运行。这堵塞了我的cpu和内存,所有的东西都堵塞了。

因此,我决定不允许超过4个sem命令排在特定id someid的队列中。

所需要的如下:

代码语言:javascript
复制
#/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 someid4实例,而rest不允许运行。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-09 13:50:54

当一个sem运行时,它会将一个pidfile添加到~/.pidfile/信号量/id-someid/中,因此您应该能够在这里对具有pids的文件进行计数。

我只是在cli中运行了两次sem --id someid -j2 sleep 10,并列出了该目录的内容:

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

所以在你的剧本里,我会

代码语言:javascript
复制
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可以包装在另一个并行进程中,该并行进程只在计算排队命令之后才将任务排在队列中:

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2020-06-23 18:45:36

我怀疑这是因为您需要在每次执行之间添加一个延迟。操作系统需要能够运行命令,然后为其他用户或进程分配一些CPU时间,然后返回并运行下一个命令。

代码语言:javascript
复制
#!/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,脚本退出。

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

https://stackoverflow.com/questions/62538776

复制
相关文章

相似问题

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