生物分子模拟论坛

 找回密码
 我想注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 987|回复: 3

[Python] 基于python和bash的多线程任务框架 不要让cpu闲着了

[复制链接]
发表于 2016-9-2 20:54:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,下载更多分子模拟资源。

您需要 登录 才可以下载或查看,没有帐号?我想注册

x
本帖最后由 pesticide_ccnu 于 2016-9-2 21:36 编辑

        在分子模拟漫漫长路中,你有没有遇到这样的情况:我有一台多核机器,也有超算账号,有几百上千乃至几十万的分子要对接,假如我想把cpu全部用起来,那该怎么办呢?一个简单的思路是开多个进程,简单来讲,我可以把分子均分为几个文件夹,写个脚本投递N次,最后再写脚本收集数据。此法简单直接,但是分文件夹使得数据变零散,比较烦人,
另外多个进程的话,相互之间很难通信,可能一个进程很快跑完就造成了cpu的浪费。

       下面提供两个多线程框架,可以用于几乎所有的分子模拟软件(已经有并行功能的程序只要不是把cpu吃满也可以应用),一个bash的一个python的,各有千秋。

       bash在linux下几乎无所不能,其优势是能很好的与机器通信以获取任务的相关信息,有些功能是其他语言或者工具无法完成的,调用起计算程序特别方便(所以一个看似麻烦
的功能也许只需要几句话,比如诸多配体对接到同一个蛋白中),缺点在于数学计算,矩阵操作写起脚本来麻烦且跑起来慢。python给我的感觉是灵活,对于有一定复杂性的任务,
因为其强大的数学计算,向量和矩阵操作,脚本写起来快,运行也快,诸多实用模块也能满足很多功能。

       扯远了点。。。下面回到主题。这里提供了bash和python两种多线程解决方案,适合对于这两种语言有一定了解的同学,没有提供测试文件,因为主要是介绍框架的。              


       下面是bash的多线程框架,用ad实现多个复合物的redock(为了易于理解,简化了脚本,实际上完全可以实现自动redock,即从实验复合物获得对接预测复合物)。
可参考http://www.cnblogs.com/xuxm2007/p/5820633.html了解更多。

[Bash shell] 纯文本查看 复制代码
#! /bin/bash
##########################################################################################################
#part1:defile your job(第一部分,定义单核任务,需要根据你的实用任务改动)
date >>time
Nproc=40                                    #prcocess used here (要用的线程数)
ls *ligand.mol2 >list                    #list of jobs (所有的任务放到一个list里面)
Njob=$(echo $(cat list|wc -l)+1|bc)         #total jobs+1 (统计总任务数目)
function jobrun                                       #define your job (定义一个函数任务)
{
j=$(cat list|sed -n "$1"p|cut -c 1-4)         #$1 is a parameter for jobid ($1作为函数输入 即任务号 这里首先要找到任务号对应的分子)
prepare_dpf42.py -l $j"_ligand.pdbqt" -r $j"_receptor.pdbqt" -o tmp2 #(为了简单期间这里没有写如何计算格子 如何计算格点文件  这里是从准备dpf文件开始)
autodock4 -p $j.dpf -l $j.dlg #(对接)
}
##############################################################################################################
#part2:mutiple process framwork (第二部分,多线程框架,可以不用懂不用改动)
PID=()                                 #PID is an array to store the pid of your job (PID 用于储存每个线程的pid)
for ((i=1;i<Njob;))
do
for  ((Ijob=0; Ijob<Nproc; Ijob++)); 
do
if [[ $i -ge $Njob ]]; #(如果任务都完成了就退出循环)
then
break;
fi
if [[ ! "${PID[Ijob]}" ]] || ! kill -0 ${PID[Ijob]} 2> /dev/null; then #(如果线程没有被占用)
echo start $i with $Ijob
jobrun $i $Ijob&      #(用Ijob线程执行任务i)
PID[Ijob]=$!           #(任务完成 释放线程Ijob)
i=$((i+1))
fi
done
##########################################################################################
wait #(等所有线程都空闲下来)
done
echo job finished!
date >>time      


下面是python版本 用于实现批量vina对接筛选。参考 http://blog.chinaunix.net/uid-26990529-id-3390814.html
[Python] 纯文本查看 复制代码
#!/usr/bin/python
import re,os,multiprocessing
#part1:defile job                      (定义一个带参数的函数)
def f(ligand):
  os.popen('prepare_ligand4.py -l '+ligand+'.mol2')
  os.popen('vina --config '+ligand+' --log '+ligand+'.txt')
  os.popen('rm '+ligand+'.mol2')

os.popen('cat /proc/cpuinfo | grep "processor" | wc -l > cpu') #读取cpu信息以统计cpu数目
fi=open('cpu').readlines()
a=int(fi[0].split()[0])                                                                #a是cpu数目 也就是线程数目
#part2:mutiple process framwork (第二部分,多线程框架,可以不用懂不用改动)
if __name__ == "__main__":
  pool=multiprocessing.Pool(processes=a) #开a个线程
  lig=os.listdir(pathfirst+'//database') #获取分子列表
  for i in lig:
    p,q=os.path.splitext(i)
    pool.apply_async(f,(p,))                                                          #调用函数,以分子名作为参数输入函数f
    pool.close()
    pool.join()


       可以看到,两种语言基本都包含两个部分,第一个部分要定义一个函数,将模拟的命令放进去,一般需要一些参数(这里是分子序号或者分子名)作为输入。
根据模拟类型不通,内容也不同。第二部分是多线程框架,一般不需要改动。
       两种方法各有千秋,bash的方法多线程框架部分相对复杂,但是定义起函数非常方便。python方法因为有专门的模块,所以多线程功能更加灵活强大。另有
perl版本的因为我自己也看不懂,故此处就不列举了。






评分

参与人数 2金币 +100 收起 理由
川大-灰太狼 + 50 神马都是浮云!版主发力了哈哈。.
墨竹晓风 + 50 很给力!

查看全部评分

发表于 2016-9-2 21:23:30 | 显示全部楼层
牛人啊!俺好好学习一下
发表于 2016-9-4 20:54:44 | 显示全部楼层
哈哈,原创好文!绝对python学习好范本。
您需要登录后才可以回帖 登录 | 我想注册

本版积分规则

QQ|分迪科技|小黑屋|手机版|Archiver|生物分子模拟论坛 ( 蜀ICP备14009200号-3

GMT+8, 2018-6-25 10:19 , Processed in 0.137183 second(s), 31 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表