农村四月闲人少,勤学苦攻把名扬。这篇文章主要讲述shell脚本线程并发控制 #yyds干货盘点#相关的知识,希望能为你提供帮助。
shell并发控制
1.文件描述符File Descriptors (FD,文件描述符或文件句柄):进程使用文件描述符来管理打开的文件
查看当前进程的fd
确定以下三点
如何exec打开一个文件
?exec 3<
>
file1.txt
如何exec关闭一个文件(释放文件句柄)
如果没有释放句柄,文件删除后描述符依然还在
?exec 3<
&
-
当一个文件FD未被释放,删除源文件也不会影响FD
?rm -rf file1
【shell脚本线程并发控制 #yyds干货盘点#】?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<
&
-
2.再谈管道管道分为匿名管道和命名管道
我们平时用的|叫匿名管道,其实匿名管道也是一个文件,只不过他是在我们心目中的,而命名管道是名副其实的文件,由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
终端2
brw-rw----1 root disk8,0 2月10 21:36 sda
brw-rw----1 root disk8,1 2月10 21:36 sda1
brw-rw----1 root disk8,2 2月10 21:36 sda2获得内容再次查看则内容小时,若想再看则重新定向到文件
3.并发控制实例脚本实现多线程并发控制的原理:
?首先定义并发的数量,然后创建管道文件,并往管道文件中插入数据(可以是空行),然后定义分隔符,以分隔符xx运行管道文件,在删除管道文件,因为删除管道文件不会影响句柄,在使用read -u命令读取分隔符内容,如果能读到数据则执行对应的后台进程,如果读取不到则一直等待,并发进程并不是等所有都执行完一轮后在执行新的一轮,而是完成一个后就会返回,比如控制 的并发数是50,那么始终都会是50个后台进程一起执行,直到程序结束
3.1.ping主机实现并发控制
#!/bin/bash
#----------------------控制进程并发数量---------------------
#-------------shell多进程/多线程------------------
#定义控制并发的数量
bfsl=10#定义管道文件
fifofile=/tmp/$$.fifo#创建管道文件
mkfifo $fifofile#以文件描述符3打开管道文件
exec 3<
>
$fifofile#删除管道文件,因为文件描述符打开的文件即使删除句柄也不会被释放
rm -rf $fifofile#循环往管道文件中写入内容
for i in $(seq $bfsl)
do
echo >
&
3#这个表示只写入回车
donefor i in 1..254
do
read -u 3#-u表示对文件描述符进行读取,如果能读取则执行下面的命令,如果不能则等待ip=192.168.81.$i
ping -c1 -W1 $ip &
>
/dev/null
if [ $? -eq 0 ];
then
echo "$ip is up"
else
echo "$ip is down"
fi
echo >
&
3#由于之前是从管道文件中读走了一行,这里要在还回去一行,让后面的进程进行使用
&
done
wait
exec 3>
&
-#释放文件描述符
echo "finish.............."
3.2.创建用户实现并发控制
#!/bin/bash
#------------创建用户实现并发控制------------
#------------shell多线程/多进程-------------------
#并发数量,一次性能同时存在多少个进程
bfcs=50#管道文件
fifofile=/tmp/user_$$.fifo#创建管道文件
mkfifo $fifofile#打开管道文件并定义为分隔符4
exec 4<
>
$fifofile#删除管道文件
rm -rf $fifofile#向管道文件插入空行
for i in $(seq $bfcs)
do
echo >
&
4
donefor i in $(seq -w 1000)
do
read -u 4#读取分隔符4,如果读到行则执行下面命令,否则一直等待user=qwe$i
useradd $user
echo "123" |passwd --stdin $user &
>
/dev/null
if [ $? -eq 0 ];
then
echo "$user is created..."
fi
echo >
&
4#当运行完命令后则重新向管道文件插入新的行,以便后续进程进行使用
&
done
wait
exec 4>
&
-#当所有循环完成后释放分隔符
echo "finish........."
推荐阅读
- 一台服务器可以建设几个网站(一台服务器可以用多久?)
- CentOS7.5 配置BBR加速
- 本地主机wp-admin的WordPress-URL不起作用
- 父/同级页面处于活动状态时显示的WordPress twentyfifteen子菜单项
- WordPress标题未显示在浏览器标题栏中
- 内置产品目录的WordPress主题
- WordPress的主题(删除导航栏)
- WordPress主题(JavaScript无法正常工作)
- 由于缺少样式表,无法识别WordPress主题