shell本身是不支持多线程的,想要并发编程,可以使用多进程。
引言
shell多进程写法很方便,在执行的命令结尾加一个&符号,便可以把当前操作放到后台进程执行,而当前进程可以继续执行其他操作。直接操作,进程数量会变得不可控,比如,对一个目录下每个文件都要执行一个操作,该操作通过&放到后台进程执行,那么,当该目录下有10个文件时,就会启动10个进程,有100个文件时,就会启动100个进程。
而每个进程都是占用系统资源的,有些资源是有一定限制的,用ulimit命令可以查看
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | $ ulimit -acore file size          (blocks, -c) 0
 data seg size           (kbytes, -d) unlimited
 file size               (blocks, -f) unlimited
 max locked memory       (kbytes, -l) unlimited
 max memory size         (kbytes, -m) unlimited
 open files                      (-n) 256
 pipe size            (512 bytes, -p) 1
 stack size              (kbytes, -s) 8192
 cpu time               (seconds, -t) unlimited
 max user processes              (-u) 2784
 virtual memory          (kbytes, -v) unlimited
 
 | 
可以看到,其中,进程的栈大小限制8192k bytes,即8M,当创建100个进程时,就会占用800M内存。而当内存不够时,系统就会报错提示,
| 1
 | Resource temporarily unavailable
 | 
所以,需要对进程总数进行控制,下面说下通过管道控制的方式。
管道FIFO First In First Out
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | touch lock_f
 trap "rm -f lock_f;exec 9<&-;exec 9>&-;exit 0" 2
 
 thread_num=10
 
 temp_pipe=$$.fifo
 mkfifo $temp_pipe
 exec 9<>$temp_pipe # 绑定
 #rm -rf $temp_pipe
 
 for (( i = 0; i < thread_num; i++ )); do
 echo
 done >&9
 
 for (( i = 0; i < 20; i++ ));
 do
 {
 echo "$i wait"
 read -u9
 echo "$i start"
 if [[ -f lock_f ]]; then
 echo >&9
 exit
 fi
 sleep 2
 echo "$i end"
 echo >&9
 } &
 done
 
 wait
 
 rm lock_f
 
 exec 9>&- # 关掉输出
 exec 9<&- # 关掉输入
 
 echo "all end"
 
 | 
- 通过trap拦截编号是2的信号,然后在里面执行一些操作
- 通过lock file将中断通知给所有进程
- mkfifo创建管道,然后与系统输入输出绑定,操作系统输入输出等同于操作管道
- 使用wait,等待所有进程执行完毕