Shell 并发控制

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

进程使用文件描述符来管理打开的文件

一、文件描述符

[root@tianyun ~]# ls /proc/$$/fd
0 1 2 3 4

0, 1, and 2, known as standard input, standard output, and standard error

[root@tianyun ~]# ll /proc/$$/fd
total 0
lr-x------ 1 root root 64 Sep 6 13:32 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 2 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 15:38 255 -> /dev/pts/0

[root@tianyun ~]# touch /file1
[root@tianyun ~]# exec 6<> /file1 //打开文件

[root@tianyun ~]# ll /proc/$$/fd
total 0
lr-x------ 1 root root 64 Sep 6 13:32 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 2 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 15:38 255 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 6 -> /file1

[root@tianyun ~]# echo "tianyun" > /proc/$$/fd/6
[root@tianyun ~]# cat /proc/$$/fd/6
tianyun
[root@tianyun ~]# cat /file1
tianyun

[root@tianyun ~]# rm -rf /file1
[root@tianyun ~]# ll /proc/$$/fd
total 0
lr-x------ 1 root root 64 Sep 6 13:32 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 2 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 15:38 255 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 6 -> /file1 (deleted)

[root@tianyun ~]# cat /proc/$$/fd/6 //即使删除源文件不应影响FD内容。
yangsheng
yangsheng
[root@tianyun ~]# cp -rf /proc/$$/fd/6 /file1 //还原删除的文件

[root@tianyun ~]# exec 6<&-
[root@tianyun ~]# ll /proc/$$/fd
total 0
lr-x------ 1 root root 64 Sep 6 13:32 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 13:32 2 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 6 15:38 255 -> /dev/pts/0

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

二、管道

匿名管道

[root@tianyun ~]# rpm -qa |grep bash

命名管道

[root@tianyun ~]# mkfifo /tmp/tmpfifo       //mkfifo创建匿名管道       作用一个终端输入一个终端输出,只能作为一次输出结果。 第二次输入将会消失。
[root@tianyun ~]# file /tmp/tmpfifo
/tmp/tmpfifo: fifo (named pipe)
[root@tianyun ~]# tty
/dev/pts/0
[root@tianyun ~]# rpm -qa > /tmp/tmpfifo
[root@tianyun ~]# tty
/dev/pts/1
[root@tianyun ~]# grep bash /tmp/tmpfifo
bash-4.1.2-14.el6.x86_64

案例一:

#!/bin/bash 
exec 7<> /etc/hosts
exec 8<> /etc/sysconfig/network

while read -u 7 line
do
echo $line read -u 8 line2
echo $line2
done

exec 7<&-
exec 8<&-

案例二:

#!/usr/bin/bash
#固定线程
read -p "请输入线程数量:" xiancheng
xianchengfile=/root/nfs/xianchengfile
mkfifo $xianchengfile //虚拟管道
exec 8<>$xianchengfile //文件描述
rm -rf $xianchengfile

for i in `seq $xiancheng`
do
echo >&8 //将内容写入到描述文件中
done

for i in {1..100}
do
read -u 8 //read 读取描述文件中的内容
{
ip=192.168.101.$i
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip is up"
else
echo "$ip is down"

fi
echo >&8 //写入到描述文件中
}&
done
wait
echo "完成"
exec 8>&- //释放描述文件