python进程和线程
2015-05-18 23:09
260 查看
单进程
from multiprocessing import Process import os def run_proc(name): print 'the %s process id is %d.' %(name,os.getpid()) if __name__=='__main__': print 'the parent process id is %d.' %os.getpid() p=Process(target=run_proc,args=('test',)) print 'process will begin.' p.start() p.join() print 'process end.'
pool
# -*- coding:utf-8 -*- from multiprocessing import Pool import os,time,random #值得注意的是,各子进程是同时运行的,这一点至关重要 def f(x): #子进程的执行程序 print 'task %d id is %d' %(x,os.getpid()) start=time.time() time.sleep(random.random()*5) end=time.time() print 'task %d ran %0.2f seconds.' %(x,(end-start)) #每个子进程运行的时间是0~5秒的随机时间 if __name__=='__main__': print 'parent id is %d' %(os.getpid()) p=Pool(processes=3) #池容量为3个进程,即同时(最多)可以运行3个进程 for i in range(5): #创建5个进程,但并未开始运行(挂起) p.apply_async(f,(i,)) print 'processes will begin' p.close() #各子进程结束后,关闭pool p.join() #等待子进程结束后,主进程再结束 print 'the end' ''' 创建5个进程:我们有5名参赛运动员 池容量是3:我们有3条泳道,每条泳道上每次至多只能有一名运动员 p.apply_async,5名运动员赛前准备,未开始比赛 p.close(),一声哨响,前3名运动员率先比赛,同时执行f(x)——子进程开始运行 每名运动员开始游泳前,喊一声:我是多少号,我要开始游了! 到终点了,喊一声,我到终点了!! 第4名运动员上,虽然它游的晚,但是仍然有可能超越先游的,先到达终点 等到又有一名运动员到终点了,第5名运动员上,...... '''
进程通信,工具Queue,Pipe
# -*- coding:utf-8 -*- from multiprocessing import Queue,Process import os,time,random def write(q): for i in ['a','b','c']: print 'put %s to queue.' %i q.put(i) time.sleep(random.random()) #有了这一句才能写一个读一个,要不然还来不及读就写完了 def read(q): while True: i=q.get(True) print 'get %s from queue.' %i if __name__=='__main__': q=Queue() #两个进程都用到q,所以q是沟通进程的桥梁,先进先出! pw=Process(target=write,args=(q,)) #创建进程实例 pr=Process(target=read,args=(q,)) print 'time is ready' pw.start() pr.start() pw.join() pr.terminate()#pr是死循环,必须手动终止进程 print 'the end'
创建一个线程
# -*- coding:utf-8 -*- #pyhton多线程编程:threading高级模块 #启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行 import time,threading def loop(): #线程的执行程序 print 'thread %s is running...' %threading.current_thread().name time.sleep(3) print 'thread %s is ended.' %threading.current_thread().name print 'thread %s is running...' %threading.current_thread().name t=threading.Thread(target=loop) #创建Thread()进程实例并挂起,其实只创建了一个线程而已 #如果想给主线程创建的线程指定线程名称,可以用 t=threading.Thread(target=loop,name='subthread') t.start() #线程开始执行,即运行loop程序 t.join() #等待线程运行结束 print 'thread %s is ended.' %threading.current_thread().name
创建两个线程,看各线程间是如何共享变量的
# -*- coding:utf-8 -*- import time,threading balance=0 def runthread(n): for i in range(10000): global balance balance=balance+n balance=balance-n if __name__=='__main__': th1=threading.Thread(target=runthread,args=(5,)) th2=threading.Thread(target=runthread,args=(8,)) th1.start() th2.start() th1.join() th2.join() print balance
结果打印的balance的值是无法预料的,很大可能性不为0(具体的要用到汇编语言来解释,csapp上有述)
避免上面的情况,就要用到锁lock
# -*- coding:utf-8 -*- import time,threading balance=0 lock=threading.Lock() def runthread(n): for i in range(10000): #先获取锁 lock.acquire() try: global balance balance=balance+n balance=balance-n finally: #改完后要释放锁 lock.release() if __name__=='__main__': th1=threading.Thread(target=runthread,args=(5,)) th2=threading.Thread(target=runthread,args=(8,)) th1.start() th2.start() th1.join() th2.join() print balance锁的好处就是确保了某段关键代码只能由一个线程从头到尾完整地执行(如try段的代码就会一次性执行完),坏处当然也很多,首先是阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了。由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也无法结束,只能靠操作系统强制终止。
解释一下python的GIL锁
任何Python线程执行前,必须先获得GIL锁(解释器全局锁),然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,也就是说,对于任何Python程序,不管有多少的处理器,任何时候都总是只有一个线程在执行,即使100个线程跑在100核CPU上,也只能用到1个核(每次只有一个线程在执行,当然只用一个 核 喽!)。
ThreadLocal
# -*- coding:utf-8 -*- ''' ThreadLocal ''' import threading,time local_school=threading.local() def run_process(): print '%s in %s' %(local_school.student,threading.current_thread().name) time.sleep(2) print '%s is over' %threading.current_thread().name def runthread(mylove): local_school.student=mylove #实质相当于local_school.student[threading.current_thread().name]=mylove #根据线程的名字来标识变量,这样就不会访问错了 run_process() #在线程中调用程序,那么那个程序自然可以知道调用自己的线程的名字!!! if __name__=='__main__': th1=threading.Thread(target=runthread,name='thread1',args=('zhuma',)) th2=threading.Thread(target=runthread,name='thread2',args=('zhangpan',)) th1.start() th2.start() th2.join() th1.join()
相关文章推荐
- 进程和线程的基础知识——Python学习笔记11
- python 的进程、线程以及协程(2)
- Python 中的进程、线程、协程、同步、异步、回调
- python 自学笔记 进程和线程
- 白话Python 进程,线程,协程
- python 创建:udp tcp服务器 线程 进程 进程池 互斥锁 协程
- Python 中进程、线程、协程、IO复用
- python线程、进程与协程
- python学习——进程vs线程
- 多线程-threading和进程VS线程(python 版)
- python线程,进程,协程
- python 学习笔记7进程和线程
- Python笔记-进程Process、线程Thread、上锁
- Python之路【第十一篇】: 进程与线程理论篇
- Python(八)进程、线程、协程篇
- Python 中的进程、线程、协程、同步、异步、回调
- 操作 python -- 进程与线程 (二)
- python进程/线程如何与django框架融合
- Python_进程、线程及协程
- Python中单线程、多线程和多进程的效率对比实验