Shell 并发

shell 并发控制

多进程

文件描述符

管道

 

 

File Descriptors (FD,文件描述符)或 文件句柄:

进程使用文件描述符来管理打开的文件
$ ls /proc/$$/fd
0  1  2  255
  • 0 —— stdin(标准输入)
  • 1 —— stdout (标准输出)
  • 2 —— stderr (标准错误)

1. 查看文件描述符
~ » ll /proc/$$/fd   #$$查看当前进程pid
lrwx------. 1 root root 64 6月  10 23:00 0 -> /dev/pts/0
lrwx------. 1 root root 64 6月  10 23:00 1 -> /dev/pts/0
lrwx------. 1 root root 64 6月  10 23:00 2 -> /dev/pts/0
lrwx------. 1 root root 64 6月  10 23:00 255 -> /dev/pts/0

2. 创建文件
~ » touch file1

3. 打开文件(exec)
~ » exec 66<> file1   #手动定义描述符66

4. 查看
~ » ll /proc/$$/fd
...
lrwx------. 1 root root 64 6月  10 23:33 66 -> /root/file1 #多了66的描述符

5. 文件描述符里追加内容
~ » echo "new.." > /proc/$$/fd/66
~ » cat file1
new..

6. 删除文件,查看描述符
~ » rm -rf file1
~ » ll /proc/$$/fd/66
lrwx------. 1 root root 64 6月  10 23:33 /proc/7073/fd/66 -> /root/file1 (deleted)

7. 拷贝文件
~ » cp /proc/$$/fd/66 file1
~ » cat file1
new..

8. 关闭文件
~ » exec 66<&-

如何exec打开一个文件
如何exec关闭一个文件(释放文件句柄)
当一个文件FD未被释放,删除原文件也不会影响FD

再谈管道

1. 匿名管道
~ » rpm -qa | grep bash

2. 命名管道
~ » mkfifo /tmp/fifo1   # 创建命名管道
~ » file /tmp/fifo1
/tmp/fifo1: fifo (named pipe)

~ » tty
/dev/pts/0
~ » uptime > /tmp/fifo1

~ » tty
/dev/pts/1
~ » cat /tmp/fifo1
 00:41:28 up  1:42,  2 users,  load average: 0.00, 0.01, 0.05
 
管道也是一个文件

 

无限制并发创建用户

# 无限制并发创建用户
#!/bin/bash

for i in {1..500}
do
    {
	user=tttayyy$i
	useradd ${user}
	echo "123456" | passwd --stdin ${user} &>/dev/null
	if [ $? -eq 0 ];then
	     echo "$user is created."
	fi
    }&
done
wait
echo "ok..."

sh useradd.sh
useradd:无法锁定 /etc/passwd,请稍后再试。
useradd:无法锁定 /etc/passwd,请稍后再试。
.......

实现并发控制

#!/bin/bash

process=2  # 进程数
# 管道文件
tmp_fifofile=/tmp/$$.fifo
mkfifo ${tmp_fifofile}  # 创建管道文件 

# 打开文件描述符
exec 8<> ${tmp_fifofile}
rm -rf ${tmp_fifofile}  # 文件删除后,不影响描述符。

# 循环几次,每次打开几个后台进程
for i in `seq $process`
do
    echo >&8  # 在8 文件描述符中放入新内容。
done

for i in {1..254}
do
    read -u 8  # 每次读取一行文件描述符内容,每次循环可以循环2次。
    {
    ip=192.168.128.${i}
    ping -c1 ${ip} &>/dev/null
    if [ $? -eq 0 ];then
        echo "$ip is up"
    else
        echo "$ip is down"
    fi
    echo >&8  # 文件描述符增加新内容
    }&
done
wait  # 等前面所有的后台进程结束,执行以下命令。
exec 8<&- # 关闭文件描述符
echo "finish....."

# 实现shell并发控制,process控制并发进程数量,创建管道文件,打开文件描述符,
# 循环2次管道文件中插入两行内容,管道文件读取一行内容会减少一行内容,每次减
# 少后,继续往文件描述符中增加新内容,前两个循环读取完后结束,如果不向文件描
# 述符中增加新内容第三次脚本不会执行,通过read -u 8 与实际业务循环进行关联,
# 进行读取内容,文件描述符有内容,就会执行以下ping 操作,直到循环254次完成。

 

posted @ 2022-06-10 09:54  南哈哈  阅读(177)  评论(0)    收藏  举报