如何用shell实现基本的线程池

本文主要介绍了如何利用bash实现一个基本的线程池。

1.预备知识

  • {}&   在linux中表示整个代码块放入后台执行
  • wait  wait命令表示等待所有后台进程执行完成
  • FIFO管道文件

2.实现思路

实现进程池有很多种方式,比如创建文件来判断文件个数等。本文采用了利用fifo文件来实现线程池,同时利用了linux中read命令天然的阻塞来快速实现。

3.具体实现


创建process_pool.sh,具体脚本如下:

#!/bin/bash
 
#线程池
process_pool(){
    #判断输入参数等
    if [ $# -lt 3 ]; then
        echo "$0 process_num command [args]"
        return 1
    fi
    _process_num=$1
    shift
    _func=$1
    shift
    if [[ ! $_process_num =~ ^[0-9]+$ ]]; then
        echo "process_num must be a number"
        return 1
    fi
    if !type $_func >/dev/null 2>&1; then
        echo "comannd must be executable"
        return 1
    fi
 
    # 创建一个先进先出的管道文件
    fifo="/tmp/$$.fifo"
    mkfifo $fifo
    #创建一个文件描述符号,把FD这个文件描述符关联到这个文件
    #{FD}表示非显示的描述符
    exec {FD}<>$fifo
    rm $fifo
  
 
    # 创建槽位
    for i in $(seq $_process_num); do
        echo >&$FD
    done
  
 
    # 执行具体命令
    for arg in [email protected]; do
        read -u $FD
        {
            $_func $arg 
            echo >&$FD
        }&
    done
 
    # wait等待所有后台进程执行完成
    wait
 
    # 释放文件描述符
    exec {FD}>&-
}
 
 
#以下为测试
test(){
    echo $1
    sleep 3
    return 0
}
 
process_pool 3 ‘test‘ 1 2 3 4 5 6 7

已经在最后有一个基本的测试用例,只需

sh process_pool.sh

即可看到效果。

时间: 2024-10-14 05:30:22

如何用shell实现基本的线程池的相关文章

JDFS:一款分布式文件管理实用程序第一篇(线程池、epoll、上传、下载)

一 前言 截止目前,笔者在博客园上面已经发表了3篇关于网络下载的文章,这三篇博客实现了基于socket的http多线程远程断点下载实用程序.笔者打算在此基础上开发出一款分布式文件管理实用程序,截止目前,已经实现了 服务端/客户端 的上传.下载部分的功能逻辑.涉及到的知识点包括线程池技术.linux epoll并发技术.上传.下载等.JDFS的下载功能的逻辑部分与笔者前几篇关于JWebFileTrans(JDownload)比较类似.如果读者对socket网络下载不熟悉或者是只对下载功能感兴趣,请

tornado 异步调用系统命令和非阻塞线程池

项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. import tornado.gen from tornado.process import Subprocess @tornado.gen.coroutine def run_command(command): """run command""" p

Python 学习笔记 - 线程池

前面我们学校里如何创建多线程,当我们接到一个新的请求时,会创建一个线程,执行完毕之后又销毁掉这个线程.对于一些数目巨大,但是单个快速执行的任务,每个任务真正执行消耗的时间和线程创建销毁的时间可能都差不多.这样一来,线程的效率浪费的比较严重.因此可以考虑使用线程池的技术,预先创建一些空闲的线程,当他们接收具体任务的时候,就去直接执行了,执行完了也不销毁,接着执行下一个任务. Python里面,因为暂时还没有功能完备的线程池,因此这部分功能需要自己实现. 实现的基本原理是创建一个队列,把填充的任务数

Quartz的线程池解析

[org.quartz.core相关类图] 可以看到核心类为QuartzScheduler [QuartzScheduler构造函数] public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval) throws SchedulerException { this.resources = resources; if (resources.

GIL、定时器、线程queue、进程池和线程池

一.GIL1.什么是GIL(这是Cpython解释器) GIL本质就是一把互斥锁,那既然是互斥锁,原理都一样,都是让多个并发线程同一时间只能 有一个执行 即:有了GIL的存在,同一进程内的多个线程同一时刻只能有一个在运行,意味着在Cpython中 一个进程下的多个线程无法实现并行===>意味着无法利用多核优势 但不影响并发的实现 GIL可以被比喻成执行权限,同一进程下的所以线程 要想执行都需要先抢执行权限 2.为何要有GIL 因为Cpython解释器自带垃圾回收机制不是线程安全的(对共享数据修改

Java线程池参数

关于Java线程池的参数设置.线程池是Java多线程里开发里的重要内容,使用难度不大,但如何用好就要明白参数的含义和如何去设置.干货里的内容大多是参考别人的,加入了一些知识点的扩充和看法.希望能对多线程开发学习的童鞋有些启发和帮助. 一.Threa 关于Java线程池的参数 关于Java线程池的参数设置.线程池是Java多线程里开发里的重要内容,使用难度不大,但如何用好就要明白参数的含义和如何去设置.干货里的内容大多是参考别人的,加入了一些知识点的扩充和看法.希望能对多线程开发学习的童鞋有些启发

Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolExecutor创建线程池实例 参考: 引出线程池 线程是并发编程的基础,前面的文章里,我们的实例基本都是基于线程开发作为实例,并且都是使用的时候就创建一个线程.这种方式比较简单,但是存在一个问题,那就是线程的数量问题. 假设有一个系统比较复杂,需要的线程数很多,如果都是采用这种方式来创建线程的话,那么

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 1 2 3 4 5 6 7 new Thread(new

线程的控制和线程池

一.WaitHandle: ”.Net 中提供了一些线程间更自由通讯的工具,他们提供了通过"信号"进行通讯的机制 可以通过ManualResetEvent,AutoResetEvent(他是在开门并且一个 WaitOne 通过后自动关门)来进行线程间的通讯 waitOne:    等待开门 Set:           开门 Reset:       关门 static void Main(string[] args) { ManualResetEvent mre = new Manu