shell脚本线程并发控制 #yyds干货盘点#

农村四月闲人少,勤学苦攻把名扬。这篇文章主要讲述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........."


    推荐阅读