shell多进程实例

shell 多进程基础

  • 代码块:用 { } 囊括,作为一个整体
  • &作用:将命令放于后台处理,空闲出当前控制台以用于做其他操作
  • wait命令:等待父进程的子进程都执行结束后再执行父进程中的指令
  • trap命令:获取控制信号,并作出处理;格式:trap CAMMANDS SIGNAL
  • 通过exec执行:创建一个新的同PID的进程去处理,变量共用,执行完exec内容后,不回到原来的调用
  • 通过fork执行:创建新进程(子进程)处理,变量只能单向传递
  • 通过source执行:加载到同一进程,在同一控制台串行处理,变量共用,执行完source内容后,再回到原来的地方接着处理

多进程关键点

  1. 文件描述符:
        是一个索引值,是内核为每一个进程与进程所打开的文件的一个映射记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。
        文件与描述符关系:每一个文件描述符会对应一个打开文件;不同的文件描述符可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。
        默认描述符:/proc/self/fd (0,1,2)
        自定义描述符:
           可用范围:ulimit -n 查看,再除去默认的0,1,2

  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 [email protected] "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 [email protected] "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

猜你喜欢

转载自blog.51cto.com/11424123/2126721