shell 多进程基础
- 代码块:用 { } 囊括,作为一个整体
- &作用:将命令放于后台处理,空闲出当前控制台以用于做其他操作
- wait命令:等待父进程的子进程都执行结束后再执行父进程中的指令
- trap命令:获取控制信号,并作出处理;格式:trap CAMMANDS SIGNAL
- 通过exec执行:创建一个新的同PID的进程去处理,变量共用,执行完exec内容后,不回到原来的调用
- 通过fork执行:创建新进程(子进程)处理,变量只能单向传递
- 通过source执行:加载到同一进程,在同一控制台串行处理,变量共用,执行完source内容后,再回到原来的地方接着处理
多进程关键点
-
文件描述符: 是一个索引值,是内核为每一个进程与进程所打开的文件的一个映射记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。 文件与描述符关系:每一个文件描述符会对应一个打开文件;不同的文件描述符可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。 默认描述符:/proc/self/fd (0,1,2) 自定义描述符: 可用范围:ulimit -n 查看,再除去默认的0,1,2
-
管道:类似于队列 特点: 对管道的读写操作应同时进行,不然操作就会被滞留 按行为单位进行操作 匿名管道:常用的“|”,前一个命令的标准输出作为下一个命令的标准输入 有名管道:一般作为任务队列,有序存取 使用mkfifo命令创建一个有名管道
3.管道与文件描述符关联
mkfifo /tmp/$$.fifo
exec 5 <>/tmp/$$.fifo
rm -f /tmp/$$.fifo
文件描述符与管道绑定:解决管道读写必须同时存在的特性 删除管道:系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变
多进程实例
mysql分库备份
#!/bin/bash
hour=`date +%H`
day=`date +%F`
now=`date +%F_%H`
all_dbs="no"
passwd="mysql_pass"
sshpass="ssh_pass"
dbs="db1 db2 db3 dbx dby dbz"
cpu_num=`cat /proc/cpuinfo |grep processor|wc -l`
p_fifo="/tmp/$$.pipo"
mkfifo $p_fifo
exec 111<>$p_fifo #关联文件描述符和管道
rm -f $p_fifo
trap "exec 111>&-;exec 111<&-;exit 0" 2
for ((i=1; i<=$cpu_num; i++))
do
echo >&111 #定义进程队列大小,cpu核数
done
function backup()
{
if [ $all_dbs == "no" ];then
for db in $dbs
do
read -u111 #从队列中获取一个消息,队列中消息数减一
{
dbname=`echo $db|sed "s/-/@002d/g"`
ops="--parallel=5 --compress-threads=5 --databases=$dbname"
bpath="/data1/ehr-mysql-backup/${day}/${db}"
inbackup
sleep 10
echo >&111 #添加一个消息到队列中,维持队列中消息数不变(进程个数)
} & #将代码块放后台处理
done
wait #等待所有后台进程处理完
exec 111>&- #关闭描述符,读写分开关闭
exec 111<&-
else
ops="--parallel=5 --compress-threads=5"
bpath="/data1/ehr-mysql-backup/${day}"
inbackup
fi
}
function inbackup()
{
if [ -f ${bpath}/lsn_${last}/xtrabackup_checkpoints ];then
echo "incremental_basedir found,do a increment backup"
/usr/bin/innobackupex -u root -p${passwd} --no-timestamp ${ops} --incremental --incremental_basedir=${bpath}/lsn_${last}/ --extra-lsndir=${bpath}/lsn_${now}/ ${bpath} --stream=xbstream |gzip |sshpass -p "${sshpass}" ssh -p 18122 root@10.10.10.79 "cat - > ${bpath}/${now}.xbstram.gz"
else
echo "incremental_basedir not found,do a full backup"
/usr/bin/innobackupex -u root -p${passwd} --no-timestamp ${ops} --extra-lsndir=${bpath}/lsn_${now}/ ${bpath} --stream=tar |gzip |sshpass -p "${sshpass}" ssh -p 18122 root@10.10.10.79 "cat - > ${bpath}/${now}.tgz"
fi
}
case $hour in
22)
last=`date +%F -d -yesterday`
find /data1/ehr-mysql-backup/ -name "${last}*" -type d -exec rm -r "{}" \;
day=`date +%F -d +1days`
backup
;;
10)
last=`date +%F_%H -d -12hours`
backup
;;
14|18)
last=`date +%F_%H -d -4hours`
backup
;;
*)
echo "not backup time"
;;
esac