shell指令碼併發控制詳解

2021-10-06 16:36:30 字數 3678 閱讀 7041

file descriptors (fd,檔案描述符或檔案控制代碼):程序使用檔案描述符來管理開啟的檔案

檢視當前程序的fd

確定以下三點

如何exec開啟乙個檔案

​ exec 3<> file1.txt

如何exec關閉乙個檔案(釋放檔案控制代碼)

如果沒有釋放控制代碼,檔案刪除後描述符依然還在

​ exec 3<&-

當乙個檔案fd未被釋放,刪除原始檔也不會影響fd

​ rm -rf file1

​ cp /proc/$$/3 file1

[root@localhost my_scripts]# ll /proc/$$/fd

總用量 0

lrwx------ 1 root root 64 2月 11 11:35 0 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 11:35 1 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 11:35 2 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 14:07 255 -> /dev/pts/2

建立乙個檔案

touch /root/file1.txt

exec 3<> /root/file1.txt 在當前程序開啟這個檔案,3代表檔案描述符

將檔案中輸入內容

echo "123" >/proc/$$/fd/3

cat /root/file1.txt 這是123就會出現在file1中,因為描述符3開啟了這個檔案

刪除/root/file1

rm -rf /root/file

這時ll /proc/$$/fd就會輸出如下結果

[root@localhost my_scripts]# ll /proc/$$/fd

總用量 0

lrwx------ 1 root root 64 2月 11 11:35 0 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 11:35 1 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 11:35 2 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 14:07 255 -> /dev/pts/2

lrwx------ 1 root root 64 2月 11 11:35 3 -> /root/file1.txt (deleted)

表示這個檔案已經被刪除了

根據描述符恢復刪除的檔案

cp /proc/$$/fd/3 /root/file1 檔案恢復

但是ll /proc/$$/fd/還是會提示3已經刪除,這是由於每個檔案都乙個特定的iload編號

關閉當前程序的檔案描述符

exec 3<&-

管道分為匿名管道和命名管道

我們平時用的|叫匿名管道,其實匿名管道也是乙個檔案,只不過他是在我們心目中的,而命名管道是名副其實的檔案,由mkfifo命令建立乙個命名管道檔案,命名管道檔案可以跨終端輸入,只顯示一次。

管道檔案不會被覆蓋,只有當有人讀到這個檔案才會消失

終端1

[root@localhost my_scripts]# mkfifo /tmp/fifo1

終端2[root@localhost ~]# grep 'sda' /tmp/fifo1 等待輸入

終端1[root@localhost my_scripts]# ll /dev/ > /tmp/fifo1

終端2brw-rw---- 1 root disk 8, 0 2月 10 21:36 sda

brw-rw---- 1 root disk 8, 1 2月 10 21:36 sda1

brw-rw---- 1 root disk 8, 2 2月 10 21:36 sda2 獲得內容

再次檢視則內容小時,若想再看則重新定向到檔案

指令碼實現多執行緒併發控制的原理:

​ 首先定義併發的數量,然後建立管道檔案,並往管道檔案中插入資料(可以是空行),然後定義分隔符,以分隔符xx執行管道檔案,在刪除管道檔案,因為刪除管道檔案不會影響控制代碼,在使用read -u命令讀取分隔符內容,如果能讀到資料則執行對應的後台程序,如果讀取不到則一直等待,併發程序並不是等所有都執行完一輪後在執行新的一輪,而是完成乙個後就會返回,比如控制 的併發數是50,那麼始終都會是50個後台程序一起執行,直到程式結束

#!/bin/bash

#----------------------控制程序併發數量---------------------

#-------------shell多程序/多執行緒------------------

#定義控制併發的數量

bfsl=10

#定義管道檔案

fifofile=/tmp/$$.fifo

#建立管道檔案

mkfifo

$fifofile

#以檔案描述符3開啟管道檔案

exec 3<

>

$fifofile

#刪除管道檔案,因為檔案描述符開啟的檔案即使刪除控制代碼也不會被釋放

rm -rf $fifofile

#迴圈往管道檔案中寫入內容

for i in

$(seq $bfsl)

doecho

>

&3 #這個表示只寫入回車

done

for i in

doread -u 3 #-u表示對檔案描述符進行讀取,如果能讀取則執行下面的命令,如果不能則等待

&done

wait

exec 3>

&- #釋放檔案描述符

echo

"finish.............."

#!/bin/bash

#------------建立使用者實現併發控制------------

#------------shell多執行緒/多程序-------------------

#併發數量,一次效能同時存在多少個程序

bfcs=50

#管道檔案

fifofile=/tmp/user_$$.fifo

#建立管道檔案

mkfifo

$fifofile

#開啟管道檔案並定義為分隔符4

exec 4<

>

$fifofile

#刪除管道檔案

rm -rf $fifofile

#向管道檔案插入空行

for i in

$(seq $bfcs)

doecho

>

&4done

for i in

$(seq -w 1000)

doread -u 4 #讀取分隔符4,如果讀到行則執行下面命令,否則一直等待

&done

wait

exec 4>

&- #當所有迴圈完成後釋放分隔符

echo

"finish........."

shell指令碼 迴圈及併發控制

bin bash read p input os version os version if os version 7.3 then cat etc aaa eof 就是講下面的內容寫到 etc aaa中 name cj passwd cj eofelif os version 6.4 then c...

Shell指令碼併發及併發數的控制

正常情況下,shell指令碼是序列執行的,一條命令執行完才會執行接下來的命令。如下 bin bash for i in seq 1 10 do echo i done echo end 指令碼執行的結果如下 123 4567 8910 end echo 1命令序列執行,如果命令耗時較長導致總時間較長...

shell指令碼的併發

2016年05月09日 17 06 28 閱讀數 1680 default模式下,shell命令是阻塞執行的,可以通過其後新增 讓這條命令非同步執行,如 sleep 10 執行這條命令後,並不會阻塞10秒,而是立即返回。如果將這種方法用在while迴圈中,則可以實現多程序並行處理。例如一下test1...