shell多進程實例
阿新 • • 發佈:2018-06-09
shell多進程 文件描述符 管道 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 [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
shell多進程實例