`

shell多线程之基于管道实现并发

阅读更多
在shell脚本里批量执行程序是比较常见的方式,如果程序很多,每个执行时间比较长,则顺序执行需要花费大量的时间。

此时并发就成为我们考虑的方向。

上篇《shell多线程》中我们已经简单实现了基于for循环的并发,可以显著提高工作效率;

缺点是CPU的核心不是无限的,如果全部占用,则会影响系统的正常运行。

这个时候我们就考虑利用linux系统的管道来进行最大并发数的管控。

1.举例:

一个厕所有10个蹲位,如果100个人来使用,则势必形成竞争,这时管理员给每个蹲位一个锁和一把钥匙,先来的人拿钥匙开锁开始使用;

蹲位全部占满后后面的人等待,当有一个蹲位空出,则交出钥匙给等待队列中的第一个人,如此循环,直到等待队列为空。

2.文件描述符

管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,解决这个问题的关键就是文件描述符了。

3. mkfifo /tmp/fd1    

创建有名管道文件exec 3/tmp/fd1,创建文件描述符3关联管道文件,这时候3这个文件描述符就拥有了管道的所有特性,还具有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,而不用关心管道内是否为空,也不用关心是否有内容写入引用文件描述符: &3可以执行n次echo >&3 往管道里放入n把钥匙

4.完整代码
#!/bin/bash

[ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道
exec 3/tmp/fd1                   #创建文件描述符,以可读()的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
rm -rf /tmp/fd1                    #关联后的文件描述符拥有管道文件的所有特性,所以这时管道文件可以删除,我们留下文件描述符来用就可以
for ((i=1;i&3                   #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌",文件描述符可以使用0/1/2/225之外的其他数字,这几个已被占用
done

for ((i=1;i&3                   #代表我这一次命令执行到最后,把令牌放回管道
}&
done
wait

exec 3&-                       #关闭文件描述符的写
4.由于从前写的脚本大部分都是以方法的形式存在的,所以想要落地就需要对上面的脚本做一些修改,保证每次循环都会执行一个方法

t1Fun(){
echo 1
}
t2Fun(){
echo 2
}
t3Fun(){
echo 3
}
t4Fun(){
echo 4
}
[ -e /tmp/fd1 ] || mkfifo /tmp/fd1
exec 3/tmp/fd1
rm -rf /tmp/fd1
for ((i=1;i&3
done

for ((i=1;i&3
}&
done
wait

exec 3&-

三、最佳实践
以队列的形式并发执行固然很好,每次并发的进程是可控的,可以提高效率还能防止系统奔溃。但是存在一个问题就是每一批的并发进程的执行时间是由这些进程里面执行最慢的决定,先前执行完的进程要等待没有执行完的进程。下面介绍并发执行的最佳实践
able File  45 lines (37 sloc)  696 Bytes
#!/bin/bash
# 并发运行的最佳实践

# 总进程数
Sp=15
# 并发数,并发数过大可能造成系统崩溃
Qp=5
# 存放进程的队列
Qarr=();
# 运行进程数
run=0
# 将进程的添加到队列里的函数
function push() {
Qarr=(${Qarr[@]} $1)
run=${#Qarr[@]}
}
# 检测队列里的进程是否运行完毕
function check() {
oldQ=(${Qarr[@]})
Qarr=()
for p in "${oldQ[@]}";do
if [[ -d "/proc/$p" ]];then
Qarr=(${Qarr[@]} $p)
fi
done
run=${#Qarr[@]}
}

# main
for((i=0; i
0
0
分享到:
评论

相关推荐

    shell的多线程&当前文件夹下批量插入MySQL

    本文将详细讲解如何在Shell脚本中实现多线程,并结合实例介绍如何批量插入MySQL数据库。 首先,我们需要理解为什么要使用多线程。在处理大量并发任务时,多线程可以并发执行任务,避免串行执行的低效,尤其在需要对...

    Shell多线程操作及线程数控制实例

    本文将深入探讨如何在Shell中实现多线程以及如何控制线程的数量。 首先,让我们从单线程实现开始。在示例中,有一个需求是检查文本文件`url.txt`中的每个URL是否有效。一个简单的单进程Shell脚本`scanUrl.sh`可以...

    操作系统实验作业——linux系统调用学习,重定向、管道、多进程、多线程编程技术实现.zip

    在本实验作业中,我们将深入学习Linux操作系统中的系统调用,并通过实践掌握重定向、管道、多进程以及多线程编程技术。下面将详细阐述这些知识点。 1. Linux系统调用: Linux系统调用是用户程序与操作系统内核交互...

    python shell

    3. **异步IO**:Python的asyncio库基于协程(coroutine)实现异步编程,它允许多个任务在单个线程内并发执行,而不是真正意义上的多线程或多进程。通过定义`async def`函数来创建协程,并使用`await`关键字等待异步...

    操作系统Shell编程

    总之,操作系统Shell编程是Linux系统管理的基础技能,涉及C程序的生命周期管理、Shell脚本编写、多线程编程以及同步机制的运用。理解和掌握这些知识点,不仅可以提高日常的系统操作效率,也是进行更复杂系统开发和...

    操作系统模拟Shell课程设计源码

    9. **多线程**:在某些高级实现中,Shell可能会使用多线程来并发处理多个命令。这需要了解Windows下的线程API,如`CreateThread`。 10. **测试与调试**:完成Shell后,需要编写测试用例以确保其正确性,同时掌握...

    wxh 操作系统模拟Shell课程设计源码.rar

    10. **多线程与并发**:在某些实现中,Shell可能需要支持多线程,以同时处理多个命令,但这通常不是基础版Shell课程设计的要求。 通过完成这样的项目,学生不仅可以掌握C/C++编程技能,还能深入理解操作系统原理,...

    在Windows下实现的shell模拟器

    10. **多线程**:在某些情况下,模拟器可能需要并发执行多个命令,这时就需要用到多线程技术。`CreateThread()`函数可以用来创建新的线程。 通过分析和实现这个“Windows下的shell模拟器”,开发者不仅可以加深对...

    Linux Shell Scripting Cookbook Linux Shell 脚本手册

    - **示例**: 探讨如何在最新的Shell环境中处理多线程或并发编程。 3. **丰富的实践案例**:每个章节都包含了易于跟随的例子,帮助读者更好地理解Shell脚本语言的特点。 - **示例**: 通过实际案例演示如何使用`sed...

    Shell脚本模拟多线程功能分享

    在Linux环境中,由于Shell本身并不支持真正的多线程编程,我们通常通过巧妙的利用管道(pipe)和重定向等机制来模拟多线程的效果。上述脚本就是通过创建FIFO(命名管道)来实现这一目的。下面将详细解析这段脚本的...

    线程脚本

    4. **线程通信**:线程间通信是多线程编程中的重要概念,如使用队列、管道、信号量、共享内存等机制进行数据交换。 5. **线程调度**:操作系统负责线程的调度,根据不同的策略(如轮转、优先级调度)分配CPU时间。 ...

    Minix_shell.rar_minix_minix shell C

    读者写者问题是多线程编程中的经典问题,涉及并发访问共享资源时的同步。在Minix中,可以通过信号量机制解决这个问题。信号量是一种同步原语,可以控制对临界区的访问。 1. **读信号量**:允许多个读者同时访问资源...

    Python基于多线程实现ping扫描功能示例

    在Python编程中,多线程是一种并发执行任务的方法,它允许多个任务同时运行,从而提高程序的效率。本示例将重点讲解如何利用多线程实现ping扫描功能,这在网络安全检测、网络拓扑发现等领域非常实用。下面我们将详细...

    百度面试题 shell

    以下是一个简单的示例,演示如何使用Shell脚本来并发执行多个任务: ```bash #!/bin/bash # 创建管道名称 tmpfile=$$.fifo mkfifo "$tmpfile" # 创建任务列表 tasks=(1 2 3 4 5) # 为并发线程创建相应个数的占位...

    shell程序实验详解

    - **理解并发程序中的同步问题**:在编写涉及多线程或多进程的程序时,理解并解决其中的同步问题至关重要。 - **提升团队合作能力**:实验过程强调团队协作的重要性,鼓励成员之间进行有效沟通和分工合作。 #### ...

    山东大学操作系统实验

    这个实验涵盖了多线程的概念,包括线程的创建、同步和通信。管道通信是一种简单的进程间通信机制,允许无亲缘关系的进程之间传递数据。学生会通过实际操作理解这两个概念,增强对并发编程的理解。 实验三:Shell...

    Linux API 和 shell MAN 手册

    `pthread_mutex_t`和`pthread_cond_t`分别用于互斥锁和条件变量,确保多线程间的同步。 3. **文件系统**:`open()`、`read()`、`write()`、`close()`等函数处理文件操作。`mkdir()`和`rmdir()`用于创建和删除目录,...

    LINUX课程设计QQ聊天

    3. **并发操作**:在Linux系统中,可以使用多线程或多进程模型实现并发。线程共享同一内存空间,通信方便但需要同步,而进程之间内存独立,通信成本相对较高。根据应用需求,可以选择合适的并发模型来确保聊天消息的...

    Linux-Shell:使用C实现Linux Shell

    - **多线程支持**:更高级的Shell可能需要支持多线程,以并发执行多个命令。 学习如何用C实现一个简单的Shell不仅可以深化对操作系统工作原理的理解,还能提升编程技能。通过分析和实践项目中的代码,你可以更好地...

Global site tag (gtag.js) - Google Analytics