Linux shell 多线程开发以及模板使用,详细一文透彻

news2024/12/25 17:41:02

Linux shell 多线程开发以及模板使用

在日常工作中,通常是起一个终端,通过 shell 连接我们的跳板机服务器,为此服务器提供一个进程供我们使用。但我们通常都是一条一条命令的运行,在某些需要并发的场景时就显得捉襟见肘。所以在大数据中,必须要学会 shell 的多线程操作,这样能够极大的提升某些重复可并发的任务的时间。

模板

先扔出模板供大家参考:

#!/bin/bash
# Copyright◎2022, Maggot. All rights reserved.
#
# This program is about concurrent program.
# Date: 2023-1-14
# Auth: huangyichun
# Version: 0.1
max_multithreading=5

[ -e /tmp/fd1_hyc ] || mkfifo /tmp/fd1_hyc
exec 3<>/tmp/fd1_hyc
rm -rf /tmp/fd1_hyc

for ((i=1;i<=$max_multithreading;i++))
do
    echo >&3
done

for loop in {1..10}
do
    read -u3
    {
        # do something like:
        echo now ${loop} is running
        sleep 3s
        echo now ${loop} is done
        
        # &3 ++
        echo >&3
    } &
done
wait 
echo all tasks done
exec 3>&-
bash loop.sh

在这里插入图片描述

可以看到,我们的打印是像是有批次似的,每批次 5 个一起打印。

代码分析

&

& 符号在 shell 中代表将该行的命令放入后台执行,比如下述程序为线性执行,循环 sleep 10s 三次,那么需要 30 秒才能运行完毕:

date
for i in {1..3}
do 
    sleep 10s; 
    echo $i done; 
done
date

在这里插入图片描述

如果我们在循环主体中,使用 &,那么可以将整个代码块放入后台(开新的子线程)运行:

date
for i in {1..3}
do 
    {
      sleep 10s; 
      echo $i done; 
    } &
done
date
jobs # 查看后台任务
pstree -ah $$ # 使用 pstree 打印当前线程树,如果命令不存在可以使用 yum -y install psmisc 进行安装

在这里插入图片描述

我们使用 {} 将循环主体进行包裹,这样整个 {……} 内容变成了一个代码块,然后使用 & 将整个代码块都在子进程中运行。那么我们主进程将会继续运行,打印时间等其他信息。

我们使用 jobs 查看了后台的任务,并且使用 pstree 命令打印了当前进程的进程树,可以看到有三个 bash sleep 挂在我们当前进程之下。等待 10 秒后,三个打印的任务同时完成,并且还有类似 [1][2][3] 的标识打印完成。

很明显,这样已经可以实现 shell 的多线程处理任务了,但有个小问题,在 java 中,线程池一定是有上限的,这样我们才能控制一个任务的最大并发数。比如当前需要运行 10000 个任务,我们不大可能直接启动 10000 个任务,而是选择 20 的并发去运行程序,所以还需要在 shell 中进行一个并发管控的方式。

令牌桶、管道 mkfifo

在流量控制中,我们可以使用令牌桶进行流量管控。类似于在一个篮子中,放入一定量的入门劵,每个人来的时候先去获取入门券,这样才能进入房间门。没有获得入门券的,会一直尝试获取入门券,然后才能进入。令牌桶也是这样,在一个桶中不断产生令牌,只有获取到令牌的,才能够去请求资源。

那么在 shell 中有类似的吗?有,那便是管道,也可以模拟类似的场景。我们一般使用 | 来创建一个无名管道,管道符左边的输出会变成右边的输入,当然这样使用是没有流量控制的。所以我们需要使用 mkfifo 来创建一个先进先出命名管道,手动放入一些令牌数据,然后需要运行的程序必须从管道中先获取令牌数据才能运行主题,否则就等待。

因为管道中的数据只会被获取一次,更有利于令牌桶的实现。

所以我们通过以下命令创建了一个先进先出管道:

# 判断是否存在,不存在时创建命令管道 fd1_hyc
[ -e /tmp/fd1_hyc ] || mkfifo /tmp/fd1_hyc
ls -ltr /tmp/fd1_hyc
file /tmp/fd1_hyc

在这里插入图片描述

这个文件的类型为 p,标示是一个 pipe 先进先出的管道。

重定向文件的描述符

在之前《Linux 重定向》章节中,我们讲解了文件描述符的使用 Linux redict 重定向 。

那个时候我们讲解了 012 分别为标准输入、标准输出、错误输出。那么如果我们想要定义其他的文件描述符,我们就可以使用 exec 来进行指定:

exec 3<>/tmp/fd1_hyc # 绑定描述符 3 与 /tmp/fd1_hyc
echo 123 > /tmp/fd1_hyc
cat /tmp/fd1_hyc # 第一次获取数据
cat /tmp/fd1_hyc # 第二次获取数据

在这里插入图片描述

上面命令将 3/tmp/fd1_hyc 文件进行了绑定,将标准输入和输出进行绑定。也就是说如果我们读取 3,等于读取 /tmp/df1_hyc 也就是我们的管道文件。进行两次 cat 获取数据的操作,但只有第一次获取到了数据,说明管道中的数据只会被读取一次,然后就消失了。

注意文件描述符为自然数,且必须大于 2,小于 limit -n

当然不能一直存在 3 这种文件操作符,在使用完毕后,通过下面命令进行释放掉,在释放之前,3 一直代表的都是管道文件:

exec 3>&- # 将描述符 3 进行释放

管道标准输入与输出

Linux 中,可以使用 read 命令来获取标准输入,而且是按照行为单位来获取数据,也就是说每次 read 都会获取单行的数据。一般用于键盘的标准输入,在之前的 shell 中也有展示。当然也可以使用 read 命令从管道中每次获取一行数据。

# 按行写入数据
echo line1 > /tmp/fd1_hyc
echo line2 > /tmp/fd1_hyc
echo line3 > /tmp/fd1_hyc
# 按行获取数据
read -u3 line ; echo $line
read -u3 line ; echo $line
read -u3 line ; echo $line
# 3 已经和 /tmp/fd1_hyc 进行了绑定

在这里插入图片描述

那么如果管道中并没有数据,read 命令会一直等待直到获取数据。当然也可以使用其他如 -t 参数设置超时时间,但这部分不在本章节讨论,各位可以查看 read 的使用手册了解。

所以刚好,我们可以使用 echo 来写入一行数据,创建令牌;然后使用 read 去读整行,消费令牌。再让每个子任务运行完毕时,也写入一行数据,创建令牌,使得其他子进程得以运行。这样便实现了整个 shell 的并发控制。

等待所有任务运行完毕

在本小节前半段,讲解了后台程序的运行。可以通过 jobs 进行查看 & 挂起的任务,那么我们也要一个方法来获取所有子进程是否都运行完毕了,这样才可以打印全部任务运行完毕或者调用某些接口。那么在 shell 中有 wait 命令可以等待当前进程的子进程全部运行完毕。

sleep 5s &
jobs
wait
jobs

在这里插入图片描述

wait 处一直等待子进程执行完毕后才执行最后的 jobs

使用场景

当并发上传数据到 hadoop 对应的目录时:

#!/bin/bash
# Copyright◎2022, Maggot. All rights reserved.
#
# This program is put file to hdfs
# Date: 2023-1-14
# Auth: huangyichun
# Version: 0.1
max_multithreading=5

[ -e /tmp/fd1_hyc ] || mkfifo /tmp/fd1_hyc
exec 3<>/tmp/fd1_hyc
rm -rf /tmp/fd1_hyc

for ((i=1;i<=$max_multithreading;i++))
do
    echo >&3
done

for filename in `ls `
do
    read -u3
    {
        echo `date` ${filename} is running
        # get filepath
        filepath=hdfs:///tmp/${${filename%%.*}}/${filename}
        hadoop fs -mkdir ${filepath}
        hadoop fs -put ${filename} ${filepath}
        echo n`date` ${filename} is done
        
        # &3 ++
        echo >&3
    } &
done
wait 
echo all tasks done
exec 3>&-

并发跑 spark-sql 任务:

#!/bin/bash
# Copyright◎2022, Maggot. All rights reserved.
#
# This program run sql sed 20 days
# Date: 2023-1-14
# Auth: huangyichun
# Version: 0.1
max_multithreading=3

[ -e /tmp/fd1_hyc ] || mkfifo /tmp/fd1_hyc
exec 3<>/tmp/fd1_hyc
rm -rf /tmp/fd1_hyc

for ((i=1;i<=$max_multithreading;i++))
do
    echo >&3
done

for date in {1..20}
do
    read -u3
    {
        date=`date -d "20230114 ${date} day" +"%Y-%m-%d"`
        echo `date` ${filename} is running
        spark-sql --master yarn --deploy-mode client --driver-cores 1 \
            --driver-memory 3G --num-executors 3 --executor-cores 1 \
            --executor-memory 4G --queue root.users.hive -f /home/huangyichun/sql/sqls/${date}.sql
        echo n`date` ${filename} is done

        echo >&3
    } &
done
wait 
echo all tasks done
exec 3>&-

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

读取和写入音频文件

将数据写入到音频文件&#xff0c;获取文件信息&#xff0c;然后将数据读回到 MATLAB 工作区。 写入音频文件 获取有关音频文件的信息 读取音频文件 绘制音频数据图 写入音频文件 从文件 handel.mat 加载示例数据 load handel.mat 工作区现在包含音频数据矩阵 y 和采样率 …

Linux 中断子系统(六):核心数据结构

Linux中断子系统有六个核心数据结构,分别是: irq_desc irq_data irqactions irq_chip irq_domain irq_domain_ops关系如下: 强烈建议大家学习一个子系统之前,先研究这个子系统的核心数据结构,知道了他们的关系,你就知道这个子系统在做什么事情。 右侧的 irq_chip、irq…

(nio)Selector-处理消息边界-附件与扩容

⚠️ 不处理边界的问题 以前有同学写过这样的代码&#xff0c;思考注释中两个问题&#xff0c;以 bio 为例&#xff0c;其实 nio 道理是一样的 public class Server {public static void main(String[] args) throws IOException {ServerSocket ssnew ServerSocket(9000);whi…

算法训练营第四天| 24. 两两交换链表中的节点 | 19.删除链表的倒数第N个节点 | 面试题 02.07. 链表相交 |142.环形链表II

24.两两交换链表中的节点 看完题后的思路 用两个指针pre,q指向1,2,创建一个虚拟头结点,使用尾插法插入**.难点在于初始条件的两个指针判空与终止条件的判断(奇数个节点与偶数个节点)** 初始节点判空无非三种情况,空节点,一个节点,直接使用一个判断解决 当个数是奇数时,pre指向…

Alluxio 2022技术干货年终大赏

2022&#xff0c;我们积累了很多应用案例&#xff0c;邀请了很多嘉宾参与了我们的社区直播活动 17场主题活动&#xff08;Alluxio Day、Meetup、Datafun Summit等&#xff09; 44位嘉宾44个主题&#xff08;来自一线大厂的实战者&#xff09; 2000分钟的分享时长&#xff08;内…

【项目实战】使用Maven打包生成jar包到指定目录

一、背景&#xff08;Maven打包存在的问题&#xff09; Maven默认打包后&#xff0c;jar文件都是生成在各自服务的target下&#xff0c;对微服务的部署不太友好&#xff0c;需要整个项目上传服务器&#xff0c;里面包含了源码 二、如何解决以上问题&#xff1f; 其实可以在打…

[激光原理与应用-63]:激光器-光学-探测光、泵浦光和种子光三种光的区别

目录 种子光 泵浦光&#xff1a; 探测光&#xff1a; 种子光 种子光是用来放大出光的&#xff0c;它的作用好比在激光中增加了受激辐射的光子数&#xff0c;因此加快放大出光。 为放大器或者其它激光器产生种子光的激光器。 种子激光器是其输出光被注入到一些放大器或者其…

类(class)-结构体(struct)-共用体(union)的异同

一、"类" 的介绍在C中, 用 "类" 来描述 "对象", 所谓的"对象"是指现实世界中的一切事物。那么类就可以看做是对相似事物的抽象, 找到这些不同事物间的共同点, 如自行车和摩托车, 首先他们都属于"对象", 并且具有一定得相同点…

10道题熟练掌握并运用链表结构算法

目录 1.牛客BM3 链表中的节点每k个一组翻转 2.BM4 合并两个排序的链表 3.BM5 合并k个已排序的链表 4.BM6 判断链表中是否有环 5.BM7 链表中环的入口结点 6.BM8 链表中倒数最后k个结点 7.BM9 删除链表的倒数第n个节点 8.BM10 两个链表的第一个公共结点 9.BM11 链表相加(…

将写好的.py/.java程序变成.exe文件

目录 一、背景 1.1、前言 1.2、说明 二、优点与缺点分析 2.1、优点 2.2、缺点 三、将.py变成.exe步骤 3.1、下载需要的库 3.2、pycharm控制台.py->.exe文件 3.3、命令行.py->.exe文件 四、.py->.exe->执行.exe可能会遇到的报错与解决办法 4.1、pyinsta…

第2章 ESP32 日志

ESP32 日志 UART配置 新建工程 查看->命令面板&#xff0c;输入esp-idf:new project&#xff0c;一路完成工程创建选择menuconfig&#xff0c;输入UART 输入UART 自定义波特率改为&#xff1a;460800 日志打印 ESP32的日志打印函数 ESP_LOGx分成5个等级&#xff1a;err…

前端笔记总结+注册登录页案例

day 1 前端开发 目的&#xff1a;开发一个平台&#xff08;网站&#xff09; 前端开发&#xff1a;HTML、CSS、JavaScript Web框架&#xff1a;接收请求并处理 - Flask、Djiango MySQL数据库&#xff1a;存储数据的地方快速上手&#xff1a;基于Flask Web框架快速搭建一个网站…

Spring Cloud Alibaba商城实战项目(day02)

四、搭建Spring Cloud Alibaba环境 4.1、简介 官方文档&#xff1a;https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html 我们所选用的组件&#xff1a; SpringCloud Alibaba - Nacos&#xff1a;注册中心&#xff08;服务发现/注册&#xf…

还不会二分查找?看这一篇就够了

目录一、整数二分1.1 二分查找模板1.1.1 寻找右边界的二分查找1.1.2 寻找左边界的二分查找1.2 应用&#xff1a;寻找元素的起始位置和终止位置二、浮点数二分2.1 浮点数二分模板2.2 应用&#xff1a;数的三次方根三、使用STL进行二分查找3.1 std::binary_search3.2 std::lower_…

27-Golang中的错误处理机制

Golang中的错误处理机制说明基本说明使用deferrecover处理上述代码错误处理机制的好处自定义错误说明 package main import ("fmt" )func test() {num1 : 10num2 : 0res : num1 / num2fmt.Println("res", res) }func fmt() {test ()fmt.Println("mai…

分享77个Java源码,总有一款适合您

Java源码 分享77个Java源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后可以看到。 源码下载链接&#xff1a;https://pan.baidu.com/s/1EhB4snvWia5eCztyfiX_2A?pwdbofo …

wish、亚马逊、ebay、沃尔玛自养号测评补单优势之分析技巧

测评补单的资源可以说是卖家非常宝贵的财富&#xff0c;通过测评补单和广告相结合&#xff0c;可以快速有效的提升店铺的产品销量&#xff0c;提高转化&#xff0c;提升listing权重&#xff0c;如果是做自养号还可以不用担心以后被别人牵制&#xff0c;毕竟资源掌握在自己手上&…

docker-基础实战第二课

Docker三剑客 Docker 镜像&#xff08;Image&#xff09;&#xff1a;镜像可以用来创建容器&#xff0c;一个镜像可以创建多个容器。 容器&#xff1a;容器实例就是指实际运行的实例&#xff0c;可以理解为镜像是java的类&#xff0c;容器就是new出来的对象。 仓库&#xff1a;…

elasticsearch实现基于拼音搜索

1、背景 一般情况下&#xff0c;有些搜索需求是需要根据拼音和中文来搜索的&#xff0c;那么在elasticsearch中是如何来实现基于拼音来搜索的呢&#xff1f;可以通过elasticsearch-analysis-pinyin分析器来实现。 2、安装拼音分词器 # 进入 es 的插件目录 cd /usr/local/es/…

【论文阅读 CIKM2011】Finding Dimensions for Queries

文章目录ForewordAbsMethodList ExtractionList WeightingList ClusteringDimension and Item RankingForeword This paper is from CIKM2011, so we only condier the method, not resultsThere are many papers that have not been shared. More papers can be found in: Sh…