Linux shell中的File Descriptor可以理解为一个指向文件的指针。默认有三个FD:0,1,2。分别指向的是:Keyboard设备文件,Moniter设备文件,和Moniter设备文件。
Shell中还允许有3..9的FD,默认都没有打开,可以认为指向的为null。
可以通过一下命令查看得开的FD:
ls /proc/self/fd
返回的数字代表FD的值。
利用重定向可以为一个FD赋值,使其指向一个非null的文件,其实就是打开一个FD。
6>&1
可以理解为将FD6指针指向FD1指针指向的文件,既Moniter。这样,FD6和FD1就同时指向同一个文件:Moniter。
6>&-
可以理解为将FD6指针置为空值null,即关闭FD6。
一个重定向只在当前命令中有效。通过exec可以使IO重定向在当前shell中长期有效。
exec 6>&1
# 关闭FD6。
exec 6>&-
"FIFO"是一种特殊的文件类型,它允许独立的进程通讯。 一个进程打开FIFO文件进行写操作,而另一个进程对之进行读操作, 然后数据便可以如同在shell或者其它地方常见的的匿名管道一样流线执行。mkfifo命令可以创建一个fifo
通过事先向一个fifo中写一些字符,一个进程开始前先从fifo中读走一个字符,执行完之后再写会一个字符,如果没有字符的话,该线程就会等待,fifo就成了一个锁。用到的代码如下
function set_fifo_fd6() { local tmp_fifofile="/tmp/$$.fifo" mkfifo "$tmp_fifofile" exec 6<>"$tmp_fifofile" rm $tmp_fifofile return 0 } function unset_fifo_fd6() { exec 6>&- return 0 } function sub_thread_begin() { read -u6 return 0 } function sub_thread_end() { echo >&6 return 0 } function init_thread_num_fd6() { local thread_num=$1 local i for ((i=0;i<$thread_num;i++));do echo done >&6 return 0 }
下面是一个例子,输出的时候可以发现基本是三个三个一组,原因是第四个启动的线程已经读不到字符,被阻塞。
#! /bin/bash #source 上面的代码 . /home/webadmin/shell/multithread.sh set_fifo_fd6 init_thread_num_fd6 3 for (( i=0; i < 10; i++ )) do { sub_thread_begin sleep 2 echo "thread $i" sub_thread_end }& done #要有wait,等待所有线程结束 wait unset_fifo_fd6