亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來到思海網(wǎng)絡(luò),我們將竭誠為您提供優(yōu)質(zhì)的服務(wù)! 誠征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購買流程 | 付款方式 | 聯(lián)系我們 [ 會員登錄/注冊 ]
促銷推廣
客服中心
業(yè)務(wù)咨詢
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352289
點(diǎn)擊這里給我發(fā)消息  81721488
有事點(diǎn)擊這里…  376585780
有事點(diǎn)擊這里…  872642803
有事點(diǎn)擊這里…  459248018
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  380791050
技術(shù)支持
有事點(diǎn)擊這里…  714236853
有事點(diǎn)擊這里…  719304487
有事點(diǎn)擊這里…  1208894568
有事點(diǎn)擊這里…  61352289
在線客服
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  983054746
有事點(diǎn)擊這里…  893984210
當(dāng)前位置:首頁 >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

Linux Shell多進(jìn)程并發(fā)以及并發(fā)數(shù)控制

添加時間:2019-5-30 22:43:50  添加: 思海網(wǎng)絡(luò) 
本文小編為大家詳細(xì)的講解shell多進(jìn)程并發(fā),在大部分用戶眼中,所謂的多進(jìn)程 只不過是將多個任務(wù)放到后臺執(zhí)行而已,下面一起來看看吧具體的內(nèi)容吧。

1. 基礎(chǔ)知識準(zhǔn)備

1.1. linux后臺進(jìn)程

Unix是一個多任務(wù)系統(tǒng),允許多用戶同時運(yùn)行多個程序。shell的元字符&提供了在后臺運(yùn)行不需要鍵盤輸入的程序的方法。輸入命令后,其后緊跟&字符,該命令就會被送往到linux后臺執(zhí)行,而終端又可以繼續(xù)輸入下一個命令了。 
比如:

sh a.sh &
sh b.sh &
sh c.sh &
這三個命令就會被同時送往linux后臺執(zhí)行,在這個程度上,認(rèn)為這三個命令并發(fā)執(zhí)行了。

1.2. linux文件描述符

文件描述符(縮寫fd)在形式上是一個非負(fù)整數(shù)。實(shí)際上,它是一個索引值,指向內(nèi)核為每一個進(jìn)程所維護(hù)的該進(jìn)程打開文件的記錄表。當(dāng)程序打開一個現(xiàn)有文件或者創(chuàng)建一個新文件時,內(nèi)核向進(jìn)程返回一個文件描述符。每一個unix進(jìn)程,都會擁有三個標(biāo)準(zhǔn)的文件描述符,來對應(yīng)三種不同的流:

文件描述符 名稱
0 Standard Input
1 Standard Output
2 Standard Error
每一個文件描述符會對應(yīng)一個打開文件,同時,不同的文件描述符也可以對應(yīng)同一個打開文件;同一個文件可以被不同的進(jìn)程打開,也可以被同一個進(jìn)程多次打開。

在/proc/PID/fd中,列舉了進(jìn)程PID所擁有的文件描述符,例如


#!/bin/bash
source /etc/profile;
 
# $表示當(dāng)前進(jìn)程的PID
PID=$
 
# 查看當(dāng)前進(jìn)程的文件描述符指向
ll /proc/$PID/fd
echo "-------------------";echo
 
# 文件描述符1與文件tempfd1進(jìn)行綁定
( [ -e ./tempfd1 ] || touch ./tempfd1 ) && exec 1<>./tempfd1
 
# 查看當(dāng)前進(jìn)程的文件描述符指向
ll /proc/$PID/fd
echo "-------------------";echo;

[ouyangyewei@localhost learn_linux]$ sh learn_redirect.sh 
total 0
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 0 -> /dev/pts/0
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 1 -> /dev/pts/0
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 2 -> /dev/pts/0
lr-x------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 255 -> /home/ouyangyewei/workspace/learn_linux/learn_redirect.sh
-------------------
 
[ouyangyewei@localhost learn_linux]$ cat tempfd1 
total 0
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 0 -> /dev/pts/0
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 1 -> /home/ouyangyewei/workspace/learn_linux/tempfd1
lrwx------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 2 -> /dev/pts/0
lr-x------. 1 ouyangyewei ouyangyewei 64 Jan  4 22:17 255 -> /home/ouyangyewei/workspace/learn_linux/learn_redirect.sh
-------------------
上述的例子中第12行,將文件描述符1與文件tempfile進(jìn)行了綁定,此后,文件描述符1指向了tempfile文件,標(biāo)準(zhǔn)輸出被重定向到了文件tempfile中。

1.3. linux管道
在Unix或類Unix操作系統(tǒng)中,管道是一個由標(biāo)準(zhǔn)輸入輸出鏈接起來的進(jìn)程集合,因此,每一個進(jìn)程的輸出將直接作為下一個進(jìn)程的輸入,

linux管道包含兩種:

匿名管道命名管道
管道有一個特點(diǎn),如果管道中沒有數(shù)據(jù),那么取管道數(shù)據(jù)的操作就會滯留,直到管道內(nèi)進(jìn)入數(shù)據(jù),然后讀出后才會終止這一操作;同理,寫入管道的操作如果沒有讀取管道的操作,這一動作就會滯留。

1.3.1. 匿名管道
在Unix或類Unix操作系統(tǒng)的命令行中,匿名管道使用ASCII中垂直線|作為匿名管道符,匿名管道的兩端是兩個普通的,匿名的,打開的文件描述符:一個只讀端和一個只寫端,這就讓其它進(jìn)程無法連接到該匿名管道。

例如:


cat file | less
為了執(zhí)行上面的指令,Shell創(chuàng)建了兩個進(jìn)程來分別執(zhí)行cat和less。

有一點(diǎn)值得注意的是兩個進(jìn)程都連接到了管道上,這樣寫入進(jìn)程cat就將其標(biāo)準(zhǔn)輸出(文件描述符為fd 1)連接到了管道的寫入端,讀取進(jìn)程less就將其標(biāo)準(zhǔn)輸入(文件描述符為fd 0)連接到了管道的讀入端。實(shí)際上,這兩個進(jìn)程并不知道管道的存在,它們只是從標(biāo)準(zhǔn)文件描述符中讀取數(shù)據(jù)和寫入數(shù)據(jù)。shell必須要完成相關(guān)的工作。 
1.3.2. 命名管道(FIFO,F(xiàn)irst In First Out)

命名管道也稱FIFO,從語義上來講,F(xiàn)IFO其實(shí)與匿名管道類似,但值得注意:

在文件系統(tǒng)中,F(xiàn)IFO擁有名稱,并且是以設(shè)備特俗文件的形式存在的;任何進(jìn)程都可以通過FIFO共享數(shù)據(jù);除非FIFO兩端同時有讀與寫的進(jìn)程,否則FIFO的數(shù)據(jù)流通將會阻塞;匿名管道是由shell自動創(chuàng)建的,存在于內(nèi)核中;而FIFO則是由程序創(chuàng)建的(比如mkfifo命令),存在于文件系統(tǒng)中;匿名管道是單向的字節(jié)流,而FIFO則是雙向的字節(jié)流;
比如,可以利用FIFO實(shí)現(xiàn)單服務(wù)器、多客戶端的應(yīng)用程序: 



有了上面的知識準(zhǔn)備,現(xiàn)在可以開始講述,linux多進(jìn)程并發(fā)時,如何控制每次并發(fā)的進(jìn)程數(shù)。

2. linux多進(jìn)程并發(fā)數(shù)控制
最近小A需要生產(chǎn)2015年全年的KPI數(shù)據(jù)報(bào)表,現(xiàn)在小A已經(jīng)將生產(chǎn)腳本寫好了,生產(chǎn)腳本一次只能生產(chǎn)指定一天的KPI數(shù)據(jù),假設(shè)跑一次生產(chǎn)腳本需要5分鐘,那么: 
* 如果是循環(huán)順序執(zhí)行,那么需要時間:5 * 365 = 1825 分鐘,約等于 6 天 
* 如果是一次性放到linux后臺并發(fā)執(zhí)行,365個后臺任務(wù),系統(tǒng)可承受不住哦!

既然不能一次性把365個任務(wù)放到linux后臺執(zhí)行,那么,能不能實(shí)現(xiàn)自動地每次將N個任務(wù)放到后臺并發(fā)執(zhí)行呢?當(dāng)然是可以的啦。


#! /bin/bash
source /etc/profile;
 
# -----------------------------
 
tempfifo=$.fifo        # $表示當(dāng)前執(zhí)行文件的PID
begin_date=$1           # 開始時間
end_date=$2             # 結(jié)束時間
 
if [ $# -eq 2 ] 
then
    if [ "$begin_date" \> "$end_date" ]
    then
        echo "Error! $begin_date is greater than $end_date"
        exit 1;
    fi
else
    echo "Error! Not enough params."
    echo "Sample: sh loop_kpi 2015-12-01 2015-12-07"
    exit 2;
fi
 
# -----------------------------
 
trap "exec 1000>&-;exec 1000<&-;exit 0" 2
mkfifo $tempfifo
exec 1000<>$tempfifo
rm -rf $tempfifo
 
for ((i=1; i<=8; i++))
do
    echo >&1000
done
 
while [ $begin_date != $end_date ]
do
    read -u1000
    {
        echo $begin_date
        hive -f kpi_report.sql --hivevar date=$begin_date
        echo >&1000
    } &
 
    begin_date=`date -d "+1 day $begin_date" +"%Y-%m-%d"`
done
 
wait
echo "done!!!!!!!!!!"
第6~22行:比如:sh loop_kpi_report.sh 2015-01-01 2015-12-01:

$1表示腳本入?yún)⒌牡谝粋參數(shù),等于2015-01-01

$2表示腳本入?yún)⒌牡诙䝼參數(shù),等于2015-12-01

$#表示腳本入?yún)⒌膫數(shù),等于2

第13行用于比較傳入的兩個日期的大小,\>是轉(zhuǎn)義

第26行:表示在腳本運(yùn)行過程中,如果接收到Ctrl+C中斷命令,則關(guān)閉文件描述符1000的讀寫,并正常退出

exec 1000>&-;表示關(guān)閉文件描述符1000的寫

exec 1000<&-;表示關(guān)閉文件描述符1000的讀

trap是捕獲中斷命令

第27~29行:

第27行,創(chuàng)建一個管道文件

第28行,將文件描述符1000與FIFO進(jìn)行綁定,<讀的綁定,>寫的綁定,<>則標(biāo)識對文件描述符1000的所有操作等同于對管道文件$tempfifo的操作

第29行,可能會有這樣的疑問:為什么不直接使用管道文件呢?事實(shí)上這并非多此一舉,管道的一個重要特性,就是讀寫必須同時存在,缺失某一個操作,另一個操作就是滯留,而第28行的綁定文件描述符(讀、寫綁定)正好解決了這個問題

第31~34行:對文件描述符1000進(jìn)行寫入操作。通過循環(huán)寫入8個空行,這個8就是我們要定義的后臺并發(fā)的線程數(shù)。為什么是寫空行而不是寫其它字符?因?yàn)楣艿牢募淖x取,是以行為單位的

第37~42行:

第37行,read -u1000的作用就是讀取管道中的一行,在這里就是讀取一個空行;每次讀取管道就會減少一個空行

第39~41行,注意到第42行結(jié)尾的&嗎?它表示進(jìn)程放到linux后臺中執(zhí)行

第41行,執(zhí)行完后臺任務(wù)之后,往文件描述符1000中寫入一個空行。這是關(guān)鍵所在了,由于read -u1000每次操作,都會導(dǎo)致管道減少一個空行,當(dāng)linux后臺放入了8個任務(wù)之后,由于文件描述符1000沒有可讀取的空行,將導(dǎo)致read -u1000一直處于等待。


關(guān)鍵字:Linux、Shell、多進(jìn)程、并發(fā)數(shù)控制
分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國增值電信業(yè)務(wù)經(jīng)營許可證: 粵B1.B2-20030321 備案號:粵B2-20030321-1
網(wǎng)站公安備案編號:44060602000007 交互式欄目專項(xiàng)備案編號:200303DD003  
察察 工商 網(wǎng)安 舉報(bào)有獎  警警  手機(jī)打開網(wǎng)站