linux shell命名管道FIFO(多进程动态并发)
来源:互联网 发布:华为软件科技有限公司 编辑:程序博客网 时间:2024/06/03 21:40
在shell脚本中,我们想要实现多进程高并发,最简单的方法是把命令丢到后台去,如果量不大的话,没问题。 但是如果有几百个进程同一时间丢到后台去就很恐怖了,对于服务器资源的消耗非常大,甚至导致宕机。
那有没有好的解决方案呢? 当然有!
一、基础知识
1.文件描述符
文件描述符(缩写fd)在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。每一个unix进程,都会拥有三个标准的文件描述符,来对应三种不同的流:
除了上面三个标准的描述符外,我们还可以在进程中去自定义其他的数字作为文件描述符,后面例子中会出现自定义数字。每一个文件描述符会对应一个打开文件,同时,不同的文件描述符也可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。
我们可以写一个测试脚本/tmp/test.sh,内容如下:
#!/bin/bash echo "该进程的pid为$$"exec 1>/tmp/test.log 2>&1ls -l /proc/$$/fd/
执行该脚本 sh /tmp/test.sh,然后查看/tmp/test.log内容为:
总用量 0
lrwx—— 1 root root 64 11月 22 10:26 0 -> /dev/pts/3
l-wx—— 1 root root 64 11月 22 10:26 1 -> /tmp/test.log
l-wx—— 1 root root 64 11月 22 10:26 2 -> /tmp/test.log
lr-x—— 1 root root 64 11月 22 10:26 255 -> /tmp/test.sh
lrwx—— 1 root root 64 11月 22 10:26 3 -> socket:[196912101]
其中0为标准输入,也就是当前终端pts/3,1和2全部指向到了/tmp/test.log,另外两个数字,咱们暂时不关注。
2.命名管道
我们之前接触过的管道“1”,其实叫做匿名管道,它左边的输出作为右边命令的输入。这个匿名管道只能为两边的命令提供服务,它是无法让其他进程连接的。
实际上,这两个进程(cat和less)并不知道管道的存在,它们只是从标准文件描述符中读取数据和写入数据。
另外一种管道叫做命名管道,英文(First In First Out,简称FIFO)。
FIFO本质上和匿名管道的功能一样,只不过它有一些特点:
1)在文件系统中,FIFO拥有名称,并且是以设备特俗文件的形式存在的;
2)任何进程都可以通过FIFO共享数据;
3)除非FIFO两端同时有读与写的进程,否则FIFO的数据流通将会阻塞;
4)匿名管道是由shell自动创建的,存在于内核中;而FIFO则是由程序创建的(比如mkfifo命令),存在于文件系统中;
5)匿名管道是单向的字节流,而FIFO则是双向的字节流;
有了上面的基础知识储备后,下面我们来用FIFO来实现shell的多进程并发控制。
二、需求背景:
领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。
需求分析:
由于数据量比较大,单个库备份时间少则10几分钟,多则几个小时,我们算平均每个库30分钟,若一个库一个库的去备份,则需要3000分钟,相当于50个小时。很明显不可取。但全部丢到后台去备份,100个并发,数据库服务器也无法承受。所以,需要写一个脚本,能够控制并发数就可以实现了。
三、编写shell
控制并发的shell脚本示例:
#!/bin/shfunction a_sub { sleep 2; endtime=`date +%s` sumtime=$[$endtime-$starttime] echo "我是$i,运行了2秒,整个脚本已经执行了$sumtime秒"}starttime=`date +%s`export starttime##其中$$为该进程的pidtmp_fifofile="/tmp/$$.fifo"##创建命名管道mkfifo $tmp_fifofile##把文件描述符6和FIFO进行绑定exec 6<>$tmp_fifofile##绑定后,该文件就可以删除了rm -f $tmp_fifofile##并发量为3,用这个数字来控制并发数thread=3for ((i=0;i<$thread;i++));do ##写一个空行到管道里,因为管道文件的读取以行为单位 echo >&6done##循环10次,相当于要备份100个库for ((i=0;i<10;i++))do ##读取管道中的一行,每次读取后,管道都会少一行 read -u6 { a_sub || {echo "a_sub is failed"} ##每次执行完a_sub函数后,再增加一个空行,这样下面的进程才可以继续执行 echo >&6 } & ##这里要放入后台去,否则并发实现不了done##这里的wait意思是,需要等待以上所有操作(包括后台的进程)都结束后,再往下执行。wait##关闭文件描述符6的写exec 6>&-
参考链接
http://blog.csdn.net/yeweiouyang/article/details/52512522
- linux shell命名管道FIFO(多进程动态并发)
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
- Linux下进程间通信机制:FIFO(命名管道)
- Linux下进程间通信机制:FIFO(命名管道)
- Linux进程通信:命名管道FIFO小结
- Linux进程通信:命名管道FIFO小结
- 【Linux】进程间通信-命名管道FIFO
- 【Linux】进程间通信-命名管道FIFO
- Linux进程通信:命名管道FIFO小结
- 【Linux进程间通信】 - 命名管道FIFO
- 【Linux】进程间通信-命名管道FIFO
- Linux进程间通信-FIFO(命名管道)
- 【Linux】进程间通信-命名管道FIFO
- 进程间通信--命名管道(fifo)
- Linux命名管道FIFO
- 【Linux】命名管道FIFO
- Linux 命名管道FIFO
- 进程通信--命名管道(FIFO)
- Linux(CentOS)下安装Dubbo管理控制台(dubbo-admin-2.5.4)
- 内置了人工智能技术 这款4K运动相机有啥能耐? | 新品
- 对话三星张代君:Bixby到底与Siri有什么不同? | AI英雄
- jfinal+redis+maven搭建web项目
- 【AI英雄风云榜】为TA投票:谁是2017中国AI领域最牛的人?
- linux shell命名管道FIFO(多进程动态并发)
- Json
- 详解聊天机器人:它会让人类工作变得多余吗? | 行业
- 利用onNewIntent避免Activity之间的跳转传值多次实体化
- Java使用POI导出Excel工具类(反射)
- CCF CSP 201503-1 图像旋转
- Java并发编程与技术内幕:消费者-生产者模式研究
- 百度地图API去获取当前用户地理位置,不过一般都不能很精确的,百度地图的定位都是有偏移量的。
- ubuntu so make