shell脚本多线程应用
- 同事将新上线APP的一部分log交给我,让我统计下这些log中供出现了哪些deviceid
- 采用awk就可以实现这部分匹配和统计功能,还是比较简单的
- 挑战在于,这批log文件非常多非常大,单进程工作处理起来非常的慢。因此我想到了多进程方式。
- 以往需要使用shell来实现多进程时,采用以下模板
|
|
* 当任务较为简单,并发数不多时,这招很管用。然而现在log文件有好几K个,grep处理文件非常耗CPU,上述模板将会按文件数启动进程,系统的CPU Load一跃而起,泪目。
* 此时的情况是,解决问题的思路和方向没有错,方式上还需要改进。关键在于:控制并发任务,合理使用CPU。
* 如何在shell中控制并发进程数呢,我找到这样一个帖子
* http://blog.sciencenet.cn/blog-548663-750136.html
- shell脚本中控制并发任务数的大体方式是:
- 初始化token池,形成一定token空间,又能在为空时阻塞想拿token的进程
- 生成一个数组,执行任务前先从数组中获得一个元素,能够获得就继续执行,否则阻塞。数组大小最好为CPU核心数。任务执行完成后将元素放回,以供别的进程使用。
- 生成一个阻塞访问的管道pipe,先向管道中写入若干行,任务执行前从管道中获取token,任务结束后放回。
- 初始化token池,形成一定token空间,又能在为空时阻塞想拿token的进程
- 最终脚本如下所示
- 我在理解这个脚本的时候感到吃力,比如exec、read等既熟悉又陌生的指令,毕竟没写过shell脚本
- 后来我发现,man bash和man sh是第一手消息资料
- if -p $directory中,-p是什么意思,在man bash的CONDITIONAL EXPRESSIONS中
- read -u999中,-u又是什么意思,在man bash的 SHELL BUILTIN COMMANDS的read指令中
- exec 999<>$Pfifo中,man bash的REDIRECTION小节中
|
|
- 单进程方式处理这些log需要3个小时,而控制并发进程数的话只需要10分钟不到。
- 可见大部分计算资源都浪费在CPU切换上了。
参考链接
linux shell 和 lsof 等工具使用的一些tips
linux shell数据输入输出的重定向分析
lsof 一切皆文件
文件描述符与进程间通信
linux shell cocurrency并发控制
Bash脚本实现批量作业并行化
A script for running processes in parallel in Bash