shell脚本线程并发控制 #yyds干货盘点#
Posted 江晓龙的技术博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本线程并发控制 #yyds干货盘点#相关的知识,希望对你有一定的参考价值。
shell并发控制
1.文件描述符
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<&-
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 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 获得内容
再次查看则内容小时,若想再看则重新定向到文件
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 #这个表示只写入回车
done
for 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
done
for 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........."
以上是关于shell脚本线程并发控制 #yyds干货盘点#的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点#linux shell 脚本,将变量拼接到命令中。
#yyds干货盘点# shell脚本入门持续更新一天一个知识点