Linux Shell 多进程

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

前段时间,我们一直在分享podman基础知识,我感觉差不多了,收货慢慢,后面想介绍一下podman restful,我们写一个基于容器的运维平台出来,不过只是构想,目前还在看demo,余下还有时间,我们看看shell,按照规矩,我们以某个点开头,本篇我们以linux shell多进程打头。

什么是进程、进程、协程序

众所周知,在linux中是没有线程概念的,所以,linux只有进程概念

我自己的理解

什么是进程,线程,协程 他们的关系又是怎么样的?

进程是线程的集合

所以线程会共享进程的堆栈,故 线程可以使用进程的变量信息

线程是内核级别

协程是用户级别

CPU的核数 等于 内核线程的最大数量


在linux中实现简单的多进程

shell多进程需要注意的点

  1. 某些代码需要执行多进程的,需要放入后台执行,中间使用 { 代码 }& 即可, 比如: 需要讲输出hello world 写成多进程的,这样的话,就会放在后入执行了

其实这也不难理解,因为我们通常要将执行命令放入后台,一般为: ./xxxx &,脚本中也是类似的

顺序执行

执行结果

同时执行

执行结果

我们sleep时间调整的长一些,我们可以看看具体进程树

我们执行成功后,看看进程树,使用命令ps axjf

可以看到其实我们对于shell多进程,其实就是在系统中启用多个命令,仅此而已。

  1. 在执行多进程时,如果我们需要多进程执行完毕后再执行后续语句,那么,我们需要在多进程后面添加wait命令,此命令会等待后台进程执行完毕后再开始执行

我们尝试在脚本中加入wait

执行

我们可以看到,它其实是等待了3秒

这个到底有什么用? 我们通过例子说明

在linux shell中如何使用多进程错误案例

例子

有如下脚本

该脚本作用于将文件拷贝至backs , 并且将其打包为tar.gz 格式

执行结果如下

执行完毕后,我们发现backs目录中有数据,而backs.tar.gz文件则为空的压缩包

这是因为我们循环中都放入后台运行了,且没有等待执行完毕,就执行打包操作,就造成了这样的局面,拷贝还没结束,打包就结束了,这样就有空包了,我们修改一下脚本,在循环结束后,加入一个wait,这样该脚本才不会有问题

linux shell 控制进程数量

为什么我们需要控制进程数量

上述简单的多进程,能够帮助我们运维提高效率,但是也有致命缺陷,就是假设我们不知道循环次数的时候,贸然使用改脚本,则会出现问题,稍不注意就会饭碗不保,脚本如下

该脚本看上去好像没啥问题,但是我们忽略了一点,那就是数据库表到底有多少? 每张表有多大?

假设该数据库下有1w张表,每张表有100M, 那我们在1s内建立1w个连接去拉取数据库? 线上库都要玩蹦,抛出至理名言:“业务和我有一个能跑就成”?

所以基于上述原因,若无法预估执行次数,可能会导致服务器性能被压满,我们才需要控制脚本在后台中的数量。

在linux shell如何控制进程数量

我们将脚本简化一下,仅输出信息即可,稍后做出解释

执行效果如下

可以看到,程序是按照2个2个一组执行的

控制进程原理解析

创建管道文件

其实上面最主要的就是管道,众所周知,管道可以分为两种,1.匿名管道 2.命令管道 , 匿名管道就是我们最常见使用的 | 例如:ls -l | grep 123,而使用mkfifo则可以创建命令管道

exec 创建文件的标识符,系统中存在的标识符,为 012stdin,stdout,stderr, 代码中的 exec 1000<>/tmp/tests.fifo 其实定义的是输入和输出描述符,其标识符为1000

进程个数调节

这一步,它会首先向管道中写入2个值,可以发现这边是没有wait的,所以说,它会与下面并发执行

多进程本身

这个多进程语句和之前语句类似,唯一的不同是,多了一个往管道取值的动作还有复写管道的动作,以此来实现进程个数控制。

感想

在实际的运维工作中,很少使用shell 多进程,原因是因为在多数情况下,用shell编写的都是很简单的程序,什么时候需要用到shell多进程呢? 正如上述所述,我们一般在备份数据、导入导出数据库的时候,使用多进程更多,但是我们一般会控制进程,毕竟,慢不要紧,要稳一点,如果把线上环境搞瞎了,可不好玩,作为一个运维小学生,我对运维行业,或者对线上正常跑的程序,始终都保持有敬畏之心,保证所有的命令,都是经过自己思考和确认的,避免引起误操作,哎呀,说多了,后期可以讲讲,运维有些误操作后,收拾起来有多恶心。

猜你喜欢

转载自juejin.im/post/7085252318442029069