⑴ python多线程并行计算通过向线程池ThreadPoolExecutor提交任务的实现方法
Python的线程池可以有效地控制系统中并发线程的数量。
当程序中需要创建许多生存期较短的线程执行运算任务时,首先考虑使用线程池。线程池任务启动时会创建出最大线程数参数 max_workers 指定数量的空闲线程,程序只要将执行函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。配合使用 with 关键字实现任务队列完成后自动关闭线程池释放资源。
⑵ Python的多进程模块multiprocessing
众所周知,Python中不存在真正的多线程,Python中的多线程是一个并发过程。如果想要并行的执行程序,充分的利用cpu资源(cpu核心),还是需要使用多进程解决的。其中multiprocessing模块应该是Python中最常用的多进程模块了。
基本上multiprocessing这个模块和threading这个模块用法是相同的,也是可以通过函数和类创建进程。
上述案例基本上就是笔者搬用了上篇文章多线程的案例,可见其使用的相似之处。导入multiprocessing后实例化Process就可以创建一个进程,参数的话也是和多线程一样,target放置进程执行函数,args存放该函数的参数。
使用类来创建进程也是需要先继承multiprocessing.Process并且实现其init方法。
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求。
但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程。
需要注意的是,在调用join方法阻塞进程前,需要先调用close方法,,否则程序会出错。
在上述案例中,提到了非阻塞,当把创建进程的方法换为pool.apply(func, (msg,))时,就会阻塞进程,出现下面的状况。
在multiprocessing模块中还存在Queue对象,这是一个进程的安全队列,近似queue.Queue。队列一般也是需要配合多线程或者多进程使用。
下列案例是一个使用进程队列实现的生产者消费者模式。
multiprocessing支持两种进程间的通信,其中一种便是上述案例的队列,另一种则称作管道。在官方文档的描述中,multiprocessing中的队列是基于管道实现的,并且拥有更高的读写效率。
管道可以理解为进程间的通道,使用Pipe([plex])创建,并返回一个元组(conn1,conn2)。如果plex被置为True(默认值),那么该管道是双向的,如果plex被置为False,那么该管道是单向的,即conn1只能用于接收消息,而conn2仅能用于发送消息。
其中conn1、conn2表示管道两端的连接对象,每个连接对象都有send()和recv()方法。send和recv方法分别是发送和接受消息的方法。例如,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。
关于multiprocessing模块其实还有很多实用的类和方法,由于篇幅有限(懒),笔者就先写到这里。该模块其实用起来很像threading模块,像锁对象和守护线程(进程)等multiprocessing模块也是有的,使用方法也近乎相同。
如果想要更加详细的了解multiprocessing模块,请参考官方文档。
⑶ 要用python从几百万行数据的文件一行行读数据并计算,如何处理最快,哪位大牛可以指点一下
如果你的数据互相有关系的话,你就只能用readline一行完了之后再处理一行;
如果你的数据是每行不相干的,那你应该可以把文件分成几段,每段分配一个thread处理;
如果你的数据时每行不相干,而且你对数据的操作不很复杂的话,应该可以考虑用gpu来代替cpu并行处理。
⑷ python 多线程为什么没有并行
1. GIL是什么?
GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。
2. 每个CPU在同一时间只能执行一个线程
在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
⑸ python脚本运行计算软件,并把结果读取出来
importre
importos
importthreading
importshutil
defget_file_list(folder):
file_list=[];
forroot,dirs,filesinos.walk(folder):
forfinfiles:
path=root+os.path.sep+f
file_list.append(path)
returnfile_list
defget_re_file_list(file_list,re_rule):
file_list_re=[]
forfile_pathinfile_list:
ifre.search(re_rule,file_path):
file_list_re.append(file_path)
returnfile_list_re
defsearch(root,re_rule):
','
returnget_refile_list(get_file_list(root),re_rule)
defwrite2file(a_list,file_path):
f=open(file_path,'a',encoding='utf-8')
forlineina_list:
f.write(line+' ')
f.close()
defwrite1line2file(line,file_path):
f=open(file_path,'a',encoding='utf-8')
f.write(line+' ')
f.close()
defread2memory(file_path):
withopen(file_path,'r',encoding='utf8')asf:
returnf.read().split(' ')
defcp(source,target):
ifnotos.path.exists(os.path.dirname(target)):
os.makedirs(os.path.dirname(target))
shutil.(source,target)
defgrep_five(pdb_file,rec_list,lig_list):
pdb=pdb_file
target="./dock_result/"+os.path.dirname(pdb).split('/')[-1]+'.pdb'
cp(pdb,target)
fr=read2memory(pbd)
forlineinfr:
five=int(line.split('')[4])
if1<=five<=486:
rec_list.append(line)
eliffive==487:
lig_list.append(line)defmain():
ligand_root=r"./ligand"
#step1
ligand_filelist=search(ligand_root,".mol2$")
write2file(ligand_filelist,"ligand.txt")
#step2
#move*.mol2topbsa_all,rename2lig.mol2
#movescreen_pbsa/*topbsa_all
screen_pbsa_filelist=get_file_list("./screen_pbsa")
forfinligand_filelist:
target_dir="./"+"pbsa_all"+"/"+os.path.basename(f)[:-5]
target_path=target_dir+"/"+"lig.mol2"
cp(f,target_path)
forspfinscreen_pbsa_filelist:
target_path=target_dir+"/"+os.path.basename(spf)
cp(spf,target_path)
#step3A
os.system("./mmpbsa1.sh")
pdb_filelist=search("./pbsa_all",".pdb$")
rec_list=[]
lig_list=[]
forpdbinpdb_filelist:
threads.append(threading.Thread(target=grep_five,args=(pdb,rec_list,lig_list)))
fortinthreads:
t.setDaemon(True)
t.start()
t.join()
#step3B
write2file(rec_list,"rec.pdb")
write2file(lig_list,"lig1.pdb")
#step4
os.system("./mmpbsa2")
total_result_list=read2memory("total_result.out")[1]
gas=total_result_list.split("")[1]
pbtot=total_result_list.split("")[2]
gbtot=total_result_list.split("")[3]
write1line2file("GAS"+gas+"2.67")
write1line2file("PBTOT"+pbtot+"2.89")
write1line2file("GBTOT"+gbtot+"2.30")
if__name__=='__main__':
main()
⑹ python能实现并行吗
Python可以实现并行,Python可以用多进程来实现并行。
进程与线程的定义:
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
进程与线程的联系:
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
更多Python知识,请关注:Python自学网!!