线上生产环境用 shell 脚本并发执行 php ,时间长了几乎每个脚本都有大量睡眠状态的进程一直挂在后台,像这样
:
8 号唤起的进程还挂在后台
以 994032 为例,用 strace 查看状态返回:
strace -p 994032
strace: Process 994032 attached
futex(0x563cb97ec830, FUTEX_WAIT_PRIVATE, 2, NUL
Google 了 FUTEX_WAIT_PRIVATE 说是等待唤醒,但是如果不 kill 的话永远不会唤醒
查看运行时间:
ps -p 994032 -p etime
ELAPSED
8-21:56:58
shell 脚本长这样
#!/bin/bash
pid=$$
name=`basename $0`
ps -ef|awk -v p=$pid -v n=$name '$2!=p && $NF~n{system("kill "p)}' #禁止重复运行
ids=$(/usr/bin/php /www/wwwroot/index_cli.php UploadImag/get_id) #获取 id ,一般会返回几万个 ID ,格式是这样的 (1 2 3 5 6 7)
temp_fifo_file=$$.info #以当前进程号,为临时管道取名
mkfifo $temp_fifo_file #创建临时管道
exec 6<>$temp_fifo_file #创建标识为 6 ,可以对管道进行读写
rm $temp_fifo_file #清空管道内容
temp_thread=80 #进程数
for ((i=0;i<temp_thread;i++)) #为进程创建相应的占位
do
echo #每个 echo 输出一个回车,为每个进程创建一个占位
done >&6 #将占位信息写入标识为 6 的管道
for loop in $ids
do
read #获取标识为 6 的占位
{
/usr/bin/php /www/wwwroot/index_cli.php UploadImag/upload_img/id/$loop #后台执行抓取程序
echo >&6 #>>>>>当任务执行完后,会释放管道占位,所以补充一个占位
}& #>>>>>在后台执行{}中的任务
done <&6 #将标识为 6 的管道作为标准输入
wait #等待所有任务完成
exec 6>&- #关闭标识为 6 的管道
定时任务调度方式
*/5 * * * * /bin/sh /www/wwwroot/cron/UploadImag.sh
项目用 thinkphp3.1 写的历史老项目,脚本也是前人留下来的,要并发执行的时候就复制一下这个 shell 脚本模板,改一下里面的参数
发展到现在已经有几百个这样的 shell 脚本,几乎全部存在进程卡住的情况
系统是 centos7
php5.4 版本
请教这种进程卡住的情况应该怎么解决?
