shell的多进程

看执行结果:

很明显是8s

=============================

这种不占处理器却有很耗时的进程,我们可以通过一种后台运行的方式

来达到节约时间的目的。看如下改进:

用“{}”将主执行程序变为一个块,用&放入后台,四次执行全部放入后台后,我们

需要用一个wait指令,等待所有后台进程执行结束,

不然 系统是不会等待的,直接继续执行后续指令,知道整个程序结束。

看结果:

可以看到,时间已经大大缩短了!

============================

以上实验虽然达到了多线程并发的目的,但有一个缺陷,不能控制

运行在后台的进程数。

为了控制进程,我们引入了管道 和文件操作符。

无名管道: 就是我们经常使用的 例如: cat text | grep "abc"

那个“|”就是管道,只不过是无名的,可以直接作为两个进程的数据通道

有名管道: mkfilo  可以创建一个管道文件 ,例如: mkfifo fifo_file

管道有一个特点,如果管道中没有数据,那么取管道数据的操作就会停滞,直到

管道内进入数据,然后读出后才会终止这一操作,同理,写入管道的操作

如果没有读取操作,这一个动作也会停滞。

当我们试图用echo想管道文件中写入数据时,由于没有任何进程在对它做读取操作,所以

它会一直停留在那里等待读取操作,此时我们在另一终端上用cat指令做读取操作

你会发现读取操作一旦执行,写入操作就可以顺利完成了,同理,先做读取操作也是一样的:

由于没有管道内没有数据,所以读取操作一直滞留在那里等待写入的数据

一旦有了写入的数据,读取操作立刻顺利完成

以上实验,看以看到,仅仅一个管道文件似乎很难实现 我们的目的(控制后台线程数),

所以 接下来介绍 文件操作符,这里只做简单的介绍,如果不熟悉的可以自行查阅资料。

系统运行起始,就相应设备自动绑定到了 三个文件操作符   分别为 0 1 2 对应 stdin ,stdout, stderr 。

在 /proc/self/fd 中 可以看到 这三个三个对应文件

输出到这三个文件的内容都会显示出来。只是因为显示器作为最常用的输出设备而被绑定。

我们可以exec 指令自行定义、绑定文件操作符

文件操作符一般从3-(n-1)都可以随便使用

此处的n 为 ulimit -n 的定义值得

可以看到 我的 n值为1024 ,所以文件操作符只能使用 0-1023,可自行定义的 就只能是 3-1023 了。

直接上代码,然后根据代码分析每行代码的含义:

第3行:   接受信号 2 (ctrl +C)做的操作

exec 1000>&-和exec 1000<&- 是关闭fd1000的意思

生成做绑定时 可以用 exec 1000<>testfifo 来实现,但关闭时必须分开来写

> 读的绑定,< 标识写的绑定  <> 则标识 对文件描述符 1000的所有操作等同于对管道文件           testfifo的操作。

第5-7行: 分别为 创建管道文件,文件操作符绑定,删除管道文件

      可能会有疑问,为什么不能直接使用管道文件呢? 

      事实上,这并非多此一举,刚才已经说明了管道文件的一个重要特性了,那就是读写必须同           时存在,缺少某一种操作,另一种操作就是滞留,而绑定文件操作符 正好解决了这个问题。(至于为什么,我还没研究明白,有知道的 还请告知,谢谢)

第9-12 行:    对文件操作符进行写入操作。 通过一个for循环写入10个空行,这个10就是我们要定义的后台线程数量。

为什么写入空行而不是10个字符呢 ?

这是因为,管道文件的读取 是以行为单位的。

 

当我们试图用 read 读取管道中的一个字符时,结果是不成功的,而刚才我们已经证实               使用cat是可以读取的。

第17-24行:  这里假定我们有100个任务,我们要实现的时 ,保证后台只有10个进程在同步运行 。

read -u1000 的作用是:读取一次管道中的一行,在这儿就是读取一个空行。

减少操作附中的一个空行之后,执行一次任务(当然是放到后台执行),需要注意的是,              这个任务在后台执行结束以后会向文件操作符中写入一个空行,这就是重点所在,如果我们不在某种情况某种时刻向操作符中写入空行,那么结果就是:

在后台放入10个任务之后,由于操作符中没有可读取的空行,导致  read - u1000 这儿              始终停顿。后边的 就不用解释了,贴下执行结果:

每次的停顿中都能看到  只有10个进程在运行

一共耗时50s

一共100个任务,每次10个 ,每个5s 正好50s

上边的结果图之所以这么有规律,这是因为我们所执行的100个任务耗时都是相同的,

比如,系统将第一批10个任务放入后台的过程所消耗的时间 几乎可以忽略不计,也就是说

这10个任务几乎可以任务是同时运行,当然也就可以认为是同时结束了,而按照刚才的分析,

一个任务结束时就会向文件描述符写入空行,既然是同时结束的,那么肯定是同时写入的空行,

所以下一批任务又几乎同时运行,如此循环下去的。

实际应用时,肯定不是这个样子的,比如,第一个放到后台执行的任务,是最耗时间的,

那他肯定就会是最后一个执行完毕。

所以,实际上来说,只要有一个任务完成,那么下一个任务就可以被放到后台并发执行了。

时间: 2024-10-05 09:40:17

shell的多进程的相关文章

linux shell 实现多进程

作为linux系统运维或者linux下的数据库DBA,很多时候需要写一些脚本来帮组我们实现某些需求,如果脚本内的某些内容能够试下并行处理,将大大提高工作的速度. 不多说,上脚本 先举一个顺序执行的例子: [[email protected] test]# cat test.sh #!/bin/bash for i in {1..5};do sleep 1 ; echo "hello" done [[email protected] test]# time sh test.sh hell

[小知识]Shell控制多进程并行 @ Shell

Shell控制程序多进程并行执行需要使用for循环. #!/bin/bash for i in *.py do nohup python $i & done wait python b.py 比如以上这段代码,多进程并行执行当前目录的所有.py文件,wait关键字表示等待所有的python程序执行完成以后,再执行b.py文件.

shell 并发多进程同时执行

1 #!/bin/bash 2 3 SEND_THREAD_NUM=13 #设置进程数. 4 tmp_fifofile="/tmp/$$.fifo" # 脚本运行的当前进程ID号作为文件名 5 mkfifo "$tmp_fifofile" # 新建一个随机fifo管道文件 6 exec 6<>"$tmp_fifofile" # 定义文件描述符6指向这个fifo管道文件 7 rm "$tmp_fifofile" 8

SHELL网络爬虫实例剖析

前天简单分享了用 shell 写网络爬虫的一些见解,今天特地把代码发出来与51博友分享,还是那句话,爱技术.爱开源.爱linux. 针对脚本的注解和整体构思,我会放到脚本之后为大家详解. #!/bin/bash # # This script is used to grab the data on the specified industry websites # Written by sunsky # Mail : [email protected] # Date : 2014-09-14 3

[shell] Bash编程总结

由于工作需要,之前的几个月写了一些Bash脚本,主要完成自动测试.打包.安装包等.虽然相比C++编程,要简单.傻瓜,但其在类Unix系统中可以大大提高工作的效率.所以在此对脚本编程过程中一些注意事项进行简单的总结. 1. shell概述 shell是介于用户和类Unix操作系统内核(kernel)之间的一个接口,是为了保护内核不被用户误操作造成损害,在内核的周围建立一个外壳(shell). 用户通过向shell提出请求,shell解释并将请求传给内核.而多个shell请求可以写在一个文件中,便构

Linux多进程之间的文件锁

之前对于文件的操作通常在一个进程中完成,最近需要在两个进程中对同一个文件进行操作.故想到了文件锁. Linux下可以使用flock()函数对文件进行加锁解锁等操作.简单介绍下flock()函数: 表头文件  #include 定义函数  int flock(int fd,int operation); 函数说明  flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作.此函数只能锁定整个文件,无法锁定文件的某一区域. 参数  operation有下列四

Linux Shell的父子关系及内建命令

Linux Shell的父子关系及内建命令 Shell的类型 系统启动什么样的shell程序取决于你个人的用户ID配置.在/etc/passwd文件中,在用户ID记录的第7个字段中列出了默认的shell程序.只要用户登录到某个虚拟控制台终端或是在GUI中启动终端仿真器,默认的shell程序就会开始运行. 在下面的例子中,用户xiaoyu使用了GNU bash shell作为自己的默认shell程序: 1 [email protected]:/$ cat /etc/passwd 2 [...] 3

线程概念及多线程控制

多线程: 多进程:可以同时处理数据(并发/并行) 多线程:可以同时处理数据(并发/并行) 线程概念: 多进程任务处理(使用的是多个虚拟地址空间):将多个任务分解为多个程序(分解到多个进程中完成). 多线程任务处理:多个pcb 共用同一个虚拟地址空间,同时完成一个代码段中多个不同模块的功能. 进程的理解:只有一个线程的进程 线程的理解: 1.在传统操作系统中进程就是一个运行中程序中的描述信息 ——>pcb,控制程序的运行 2.linux中并没有为线程设计一个tcb 来控制线程的运行 3.在linu

shell 多进程

shell 多进程来模拟多线程 (1){ } 建立代码块 (2)使用 & 将进程放入后台 [[email protected] ~]$ cat threads.sh #!/bin/bash for ((i=0;i<5;i++)) do { sleep 3 echo $i>>aa && echo $i }& done wait cat aa | wc -l rm aa result