linux shell多进程

1 bash后台运行实现多进程

1.1 command & 后台运行

释放终端命令行,将command命令程序挂到后台继续执行,这样用户就不必等待该程序执行结束后才释放终端命令行,可以一边等待command后台执行一边做其他的事。但是,不可以关闭当前的终端,挂靠在后台的command命令是依赖于当前终端的,当关闭当前终端之后,后台的comman命令也会终止执行。
比如:使用sort指令对一个较大的文件进行排序

$ sort log > log.sorted &

1.2 nohup command & 后台运行

这种方式与之前的区别是,使用nohup来管理后台执行的command程序。这样可以是后台的command程序完全脱离终端,当终端关闭时,后台的command程序会在nohup管理下继续执行。如果你要运行一个非常耗时的程序时,建议使用nohup来管理后台程序。这是因为,当程序运行过程中,终端因为网速不稳定或者其他原因突然中断时,会导致运行中的程序中断。
使用方式:

$ nohup longtime.sh &

程序执行过程中的正常输出以及错误输出都被重定向到程序目录下的nohup.out文件中。也可以使用如下方式来指定重定向输出的文件:

$ nohup longtime.sh > myout 2>&1 &

1.3 后台任务实现多进程

只需将需要多进程执行的程序块全部使用command & 转移到后台执行即可。

#!/bin/bash
start=`date +"%s"`
for (( i=0; i<10; i++ ))
do
    {
        echo "multiprocess"
        sleep 3
    } &  #将上述程序块放到后台执行
done
wait    #等待上述程序结束
end=`date +"%s"`
echo "time: " `expr $end - $start`

使用上述方式,10次执行过程全部放到后台执行。这种方式虽然可以实现程序的多进程并发执行,但是我们无法控制运行在后台的进程数。为了实现进程数控制,需要使用管道和文件描述符。

2 使用fifo管道管理多进程

2.1 管道

管道可用于程序之间的数据共享,但是需要注意的是,这种数据共享是单向的。管道分两种:匿名管道和有名管道,这里仅讨论有名管道。
管道的特点:
1、需要有两个程序分别连接管道的两端,一个程序往管道里写数据,另一个程序从管道里取数据;
2、只有写数据的程序时,写入操作会一直处理阻塞状态,直到有另外的程序从管道中读数据;同理当只有读取的程序时,读取操作也会一直处于阻塞状态,直到有另外的程序往管道里写数据
3、当管道中没有数据时,取数据的程序会被阻塞,直到写数据的程序写数据到管道

有名管道被称为fifo有如下特点:
1、fifo拥有名称,并存在于文件系统之中
2、除非fifo两端同时存在读和写的程序,否则fifo的数据流将会阻塞
3、fifo由mkfifo这样的命令创建,而匿名管道是由shell自动创建
4、fifo是一个双向的字节流,数据流没有任何格式

2.2 使用fifo管理shell多进程

直接代码:

  1 #!/bin/bash
  2 
  3 if [ $# -ne 1 ]
  4 then
  5         echo Usage: split.sh 201610
  6         exit 1
  7 else
  8         month=$1
  9 fi
 10 len=`echo $month | wc -L`
 11 if [ $len != "6" ]
 12 then
 13         echo "err> The lenght of month is not valid ..."
 14 fi
 15 
 16 
 17 fp_out="/opt/log_combine/"
 18 fp_tmp="/opt/log_combine/tmp/"
 19 fp_in="/opt/tag_log/tag.log."
 20 
 21 #获取所有日志文件的文件名
 22 fns=`ls $fp_in$month*.gz`
 23 if ls $fns >> log.split4month
 24 then
 25         echo "split the log begin!"
 26 else
 27         echo "err> can't find the file $fns"
 28         exit 1
 29 fi
 30 
 31 trap "exec 1000>&-;exec 1000<&-;exit 0" 2
 32 
 33 tmpfifo=$$.fifo
 34 mkfifo $tmpfifo
 35 exec 1000<>$tmpfifo
 36 rm -fr $tmpfifo
 37 
 38 thread_num=`grep "processor" /proc/cpuinfo | sort -u | wc -l`
 39 
 40 for (( i=0; i<$thread_num; i++ ))
 41 do
 42         echo >&1000
 43 done
 44 
 45 for fn in $fns
 46 do
 47         fn_tmp=${fn##*/}
 48         read -u1000
 49         {
 50                 echo `date` $fn "begin!"
  51                 zcat $fn | gawk -F"\001" 'NF==6{
 52                         if($1~/\./){
 53                                 suf = substr($1, index($1, ".")-1, 1)
 54                         }else{
 55                                 suf = substr($1, length($1))
 56                         }
 57                         
 58                         if(suf~/[0-9a-f]/){
 59                                 print $1"\001"$2"\001"$4"\001"$6 >> "'$fp_tmp$fn_tmp'_" suf "_split" 
 60                         #}else{
 61                         #       print $0
 62                         }
 63                 }'
 64                 echo `date` $fn "end!"
 65                 echo >&1000
 66         } &
 67 done
 68 echo "done !!!!!!"
  • 31行:trap命令,程序接收Ctrl+c终端信号的处理
    • exec 1000>&-:关闭文件描述符1000的写
    • exec 1000<&-:关闭文件描述符1000的读
    • 2:接收的是Ctrl+c信号
  • 33-36行:
    • 33行:获取当前程序的进程号
    • 34行:mkfifo创建管道,管道名为当前进程的进程号
    • 35行:exec命令,将文件描述符1000与上述管道进行绑定,其中<是读绑定,>是写绑定,这里可以使用<>将读写同时与管道进行绑定
    • 36行:删除管道文件(不太明白为啥在这里就删除它)
    • 特别说明:这里为何要将管道文件和文件描述符进行绑定,直接使用管道文件不可以吗?答案肯定是不可以,以下内容是我自己的理解。要实现多进程控制,就必须使用两个功能:第一,管道的特殊性质(阻塞功能);第二,通过对文件描述符的read和echo操作来控制管道中的数据内容(这才是控制多进程数量的关键)。为了满足上述功能,只能是将文件描述符和fifo绑定,使文件描述符同时具有文件读写功能以及管道功能
  • 38行:获取当前系统的线程数N,以此为并行运行的进程数
  • 40-42行:向文件描述符1000中写入N的空行,用来控制并行的进程数
  • 45-67行:并行开启N的进程处理日志文件
    • 48行:要从文件描述符1000中读取一行,如果当前文件描述符1000没有任何内容,read命令就会被阻塞(由管道特点决定)
    • 49-66行:需要并行处理的程序块,其中66行最后的&表示将这个程序块放到后台执行
    • 特别说明:最初管道中有N的空行,会有N个read命令顺利执行,后续的程序快也可以继续往下执行,但是后续的一个read命令因为管道中没有任何内容全部被阻塞,当执行中的某个程序块执行到65行时,会往管道中写入一个空行,于是阻塞队列中的read命令会从管道中读取到一个空行,后续程序块被放到后台得到执行。这就是通过fifo对并行程序进行控制的关键。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容