shell多執行緒 2 之基於管道實現併發

2022-06-12 09:54:10 字數 1698 閱讀 3024

在shell指令碼裡批量執行程式是比較常見的方式,如果程式很多,每個執行時間比較長,則順序執行需要花費大量的時間。

此時併發就成為我們考慮的方向。

上篇《shell多執行緒》中我們已經簡單實現了基於for迴圈的併發,可以顯著提高工作效率;

缺點是cpu的核心不是無限的,如果全部占用,則會影響系統的正常執行。

這個時候我們就考慮利用linux系統的管道來進行最大併發數的管控。

1.舉例:

乙個廁所有10個蹲位,如果100個人來使用,則勢必形成競爭,這時管理員給每個蹲位乙個鎖和一把鑰匙,先來的人拿鑰匙開鎖開始使用;

蹲位全部佔滿後後面的人等待,當有乙個蹲位空出,則交出鑰匙給等待佇列中的第乙個人,如此迴圈,直到等待隊列為空。

2.檔案描述符

管道具有存乙個讀乙個,讀完乙個就少乙個,沒有則阻塞,放回的可以重複取,這正是佇列特性,解決這個問題的關鍵就是檔案描述符了。

3. mkfifo /tmp/fd1     

建立有名管道檔案exec 3<>/tmp/fd1,建立檔案描述符3關聯管道檔案,這時候3這個檔案描述符就擁有了管道的所有特性,還具有乙個管道不具有的特性:無限存不阻塞,無限取不阻塞,而不用關心管道內是否為空,也不用關心是否有內容寫入引用檔案描述符: &3可以執行n次echo >&3 往管道裡放入n把鑰匙

4.完整**

#!/bin/bash

[ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #建立有名管道

exec

3<>/tmp/fd1 #建立檔案描述符,以可讀(<)可寫(>)的方式關聯管道檔案,這時候檔案描述符3就有了有名管道檔案的所有特性

rm -rf /tmp/fd1 #關聯後的檔案描述符擁有管道檔案的所有特性,所以這時管道檔案可以刪除,我們留下檔案描述符來用就可以

for ((i=1;i<=10;i++))

doecho >&3 #&3代表引用檔案描述符3,這條命令代表往管道裡面放入了乙個"

令牌",檔案描述符可以使用0/1/2/225之外的其他數字,這幾個已被占用

done

for ((i=1;i<=100;i++))

doread -u3 #代表從管道中讀取乙個令牌

&done

wait

exec

3<&-#關閉檔案描述符的讀

exec

3>&- #關閉檔案描述符的寫

4.由於從前寫的指令碼大部分都是以方法的形式存在的,所以想要落地就需要對上面的指令碼做一些修改,保證每次迴圈都會執行乙個方法

t1fun()

t2fun()

t3fun()

t4fun()

[ -e /tmp/fd1 ] || mkfifo /tmp/fd1

exec

3<>/tmp/fd1

rm -rf /tmp/fd1

for ((i=1;i<5;i++))

doecho >&3

done

for ((i=1;i<=4;i++))

doread -u3

&done

wait

exec

3<&-exec

3>&-

多執行緒寫檔案 Shell簡單實現多執行緒

解決shell指令碼單執行緒下效率低下的問題 需要在linux系統執行同一項命令,但是針對不同的物件,例如ping檢測主機,當然可以延展,只要是命令之間不會產生衝突就可以了 正式開始前先了解一下下面使用到的乙個工具 nc nc是netcat的簡寫,有著網路界的瑞士軍刀美譽。因為它短小精悍 功能實用,...

Shell 實現多執行緒(多工)

bin bash all num 10 a date h m s for num in seq1 do done b date h m s echo e starttime t a echo e endtime t b 在命令的末尾加 符號,則命令將在後台執行,這樣後面的命令不需要等待該命令執行完再...

java學習筆記之多執行緒(2)之執行緒安全

1 同步 塊 synchronized obj 鎖的必須是各執行緒共享的物件 2 同步方法 synchronized 方法,對自己加鎖 synchronized this 3 同步鎖 只介紹可重入鎖 final reentrantlock lock new reentrantlock 加鎖 呼叫lo...