需求:
例如同时执行n个多卡训练python脚本(n个程序均使用相同的卡,且显存充足的前提下),或同时开启多个CPU任务python脚本。
注意:
- for循环内不要使用if-continue,会导致堵塞,改用if-else;
-
多进程启动后使用Ctrl+C终止会清理不干净,可以使用ps命令查询并kill,例如:
-
ps -aux|grep xxx.sh
查询当前有几个子进程; -
ps aux|grep xxx.sh |grep -v grep|cut -c 9-15|xargs kill -15
kill所有子进程。
-
完整代码:
#!/usr/bin/env bash
############################# 单进程 #############################
for ((i=0; i<20;i++))
do
echo $i # 执行脚本
# python .... # 执行脚本
sleep 3 # 执行脚本
done
############################# 单进程 #############################
############################# 多进程 #############################
Npro=4 #并行n个子进程
tmp_fifo="/tmp/$$.fifo" # 脚本运行的当前进程ID号作为文件名
mkfifo $tmp_fifo # 新建一个随机fifo管道文件
exec 6<>$tmp_fifo # 将fd 6指向该文件(定义文件描述符6指向这个fifo管道文件)
rm -f $tmp_fifo
for((i=1; i<=$Npro; i++)); do
echo
done >&6 # 在fd 6指向的文件(fifo)中放置$Npro个回车符,作为令牌
####### 替换原for循环 #######
for ((i=0; i<20;i++))
####### 替换原for循环 #######
do
read -u6 #从fd 6中读出减去一个回车符,然后向下执行
#如果fd 6中没有回车符了,进程阻塞在这儿
{
############## 替换原执行脚本 ##############
echo $i # 执行脚本
# python .... # 执行脚本
sleep 3 # 执行脚本
############## 替换原执行脚本 ##############
echo >&6 #向fd6加上一个回车符
} & #花括号体内的程序后台作为一个子进程执行
# 继续等待 read 中读取fifo数据,当后台的n个子进程完成python后,按次序
# 排队往fifo输入空行,这样fifo中又有了数据,for语句继续执行
done
wait
exec 6>&- #关闭fd6
############################# 多进程 #############################
版权声明:本文为qq_40156289原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。