python进程教程,python创建进程教学_第1页
python进程教程,python创建进程教学_第2页
python进程教程,python创建进程教学_第3页
python进程教程,python创建进程教学_第4页
python进程教程,python创建进程教学_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、进程程序:例如xxx.py这是程序,是一个静态的。进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元。不仅可以通过线程完成多任务,进程也是可以的。进程的状态工作中,任务数往往大于cpu的核数,即一定有一些任务正在执行,而另外一些任务在等待cpu进行执行,因此导致了有了不同的状态。就绪态:运行的条件都已经满足,正在等在cpu执行。执行态:cpu正在执行其功能。等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态。创建进程multiprocessing模块就是跨平台版本的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为

2、是一个独立的进程,可以执行另外的事情。示例:创建一个进程,执行两个死循环。from multiprocessing import Processimport timedef run_proc(): 子进程要执行的代码 while True: print(-2-) time.sleep(1)if _name_=_main_: p = Process(target=run_proc) p.start() while True: print(-1-) time.sleep(1)说明创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动方法说明Proce

3、ss( target , name , args , kwargs)target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码args:给target指定的函数传递的参数,以元组的方式传递kwargs:给target指定的函数传递命名参数name:给进程设定一个名字,可以不设定Process创建的实例对象的常用方法:start():启动子进程实例(创建子进程)is_alive():判断进程子进程是否还在活着join(timeout):是否等待子进程执行结束,或等待多少秒terminate():不管任务是否完成,立即终止子进程Process创建的实例对象的常用属性:name:当前进程

4、的别名,默认为Process-N,N为从1开始递增的整数pid:当前进程的pid(进程号)示例:from multiprocessing import Processimport osfrom time import sleepdef run_proc(name, age, *kwargs): for i in range(10): print(子进程运行中,name= %s,age=%d ,pid=%d. % (name, age, os.getpid() print(kwargs) sleep(0.2)if _name_=_main_: p = Process(target=run_pro

5、c, args=(test,18), kwargs=m:20) p.start() sleep(1) # 1秒中之后,立即结束子进程 p.terminate() p.join()Pool开启过多的进程并不能提高你的效率,反而会降低你的效率,假设有500个任务,同时开启500个进程,这500个进程除了不能一起执行之外(cpu没有那么多核),操作系统调度这500个进程,让他们平均在4个或8个cpu上执行,这会占用很大的空间。如果要启动大量的子进程,可以用进程池的方式批量创建子进程:def task(n): print(-start.format(n) time.sleep(1) print(-en

6、d.format(n)if _name_ = _main_: p = Pool(8) # 创建进程池,并指定线程池的个数,默认是CPU的核数 for i in range(1, 11): # p.apply(task, args=(i,) # 同步执行任务,一个一个的执行任务,没有并发效果 p.apply_async(task, args=(i,) # 异步执行任务,可以达到并发效果 p.close() p.join()进程池获取任务的执行结果:def task(n): print(-start.format(n) time.sleep(1) print(-end.format(n) retu

7、rn n * 2if _name_ = _main_: p = Pool(4) for i in range(1, 11): res = p.apply_async(task, args=(i,) # res 是任务的执行结果 print(res.get() # 直接获取结果的弊端是,多任务又变成同步的了 p.close() # p.join() 不需要再join了,因为 res.get()本身就是一个阻塞方法异步获取线程的执行结果:import timefrom multiprocessing.pool import Pooldef task(n): print(-start.format(

8、n) time.sleep(1) print(-end.format(n) return n * 2if _name_ = _main_: p = Pool(4) res_list = for i in range(1, 11): res = p.apply_async(task, args=(i,) res_list.append(res) # 使用列表来保存进程执行结果 for re in res_list: print(re.get() p.close()进程间不能共享全局变量from multiprocessing import Processimport osnums = 11, 2

9、2def work1(): 子进程要执行的代码 print(in process1 pid=%d ,nums=%s % (os.getpid(), nums) for i in range(3): nums.append(i) print(in process1 pid=%d ,nums=%s % (os.getpid(), nums)def work2(): 子进程要执行的代码 nums.pop() print(in process2 pid=%d ,nums=%s % (os.getpid(), nums)if _name_ = _main_: p1 = Process(target=wo

10、rk1) p1.start() p1.join() p2 = Process(target=work2) p2.start() print(in process0 pid= ,nums=.format(os.getpid(),nums)运行结果:in process1 pid=2707 ,nums=11, 22in process1 pid=2707 ,nums=11, 22, 0in process1 pid=2707 ,nums=11, 22, 0, 1in process1 pid=2707 ,nums=11, 22, 0, 1, 2in process0 pid=2706 ,nums=

11、11, 22in process2 pid=2708 ,nums=11线程和进程功能进程,能够完成多任务,比如 在一台电脑上能够同时运行多个QQ。线程,能够完成多任务,比如 一个QQ中的多个聊天窗口。定义的不同进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。区别一个程序至少有一个进程,一个进程至少有一个线程.线程的划分尺度小于进程(资源比进程少),使得多线

12、程程序的并发性高。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率线线程不能够独立执行,必须依存在进程中可以将进程理解为工厂中的一条流水线,而其中的线程就是这个流水线上的工人优缺点线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。进程间通信-Queuefrom multiprocessing import Queueq=Queue(3) #初始化一个Queue对象,最多可接收三条put消息q.put(消息1) q.put(消息2)print(q.full() #Falseq.put(消息3)print(q.full()

13、#True#因为消息列队已满下面的try都会抛出异常,第一个try会等待2秒后再抛出异常,第二个Try会立刻抛出异常try: q.put(消息4,True,2)except: print(消息列队已满,现有消息数量:%s%q.qsize()try: q.put_nowait(消息4)except: print(消息列队已满,现有消息数量:%s%q.qsize()#推荐的方式,先判断消息列队是否已满,再写入if not q.full(): q.put_nowait(消息4)#读取消息时,先判断消息列队是否为空,再读取if not q.empty(): for i in range(q.qsize

14、(): print(q.get_nowait()说明初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);Queue.qsize():返回当前队列包含的消息数量;Queue.empty():如果队列为空,返回True,反之False ;Queue.full():如果队列满了,返回True,反之False;Queue.get(block, timeout):获取队列中的一条消息,然后将其从列队中移除,block默认值为True;1)如果block使用默认值,且没有设置timeout(单位秒

15、),消息列队如果为空,此时程序将被阻塞(停在读取状态),直到从消息列队读到消息为止,如果设置了timeout,则会等待timeout秒,若还没读取到任何消息,则抛出Queue.Empty异常;2)如果block值为False,消息列队如果为空,则会立刻抛出Queue.Empty异常;Queue.get_nowait():相当Queue.get(False);Queue.put(item,block, timeout):将item消息写入队列,block默认值为True;1)如果block使用默认值,且没有设置timeout(单位秒),消息列队如果已经没有空间可写入,此时程序将被阻塞(停在写入状

16、态),直到从消息列队腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没空间,则抛出Queue.Full异常;2)如果block值为False,消息列队如果没有空间可写入,则会立刻抛出Queue.Full异常;Queue.put_nowait(item):相当Queue.put(item, False);使用Queue实现进程共享我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:from multiprocessing import Process, Queueimport os, time, random# 写数据进程执行

17、的代码:def write(q): for value in A, B, C: print(Put %s to queue. % value) q.put(value) time.sleep(random.random()# 读数据进程执行的代码:def read(q): while True: if not q.empty(): value = q.get(True) print(Get %s from queue. % value) time.sleep(random.random() else: breakif _name_=_main_: # 父进程创建Queue,并传给各个子进程:

18、q = Queue() pw = Process(target=write, args=(q,) pr = Process(target=read, args=(q,) # 启动子进程pw,写入: pw.start() # 等待pw结束: pw.join() # 启动子进程pr,读取: pr.start() pr.join() print(所有数据都写入并且读完)进程池当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool

19、方法。初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务,请看下面的实例:from multiprocessing import Poolimport os, time, randomdef worker(msg): t_start = time.time() print(%s开始执行,进程号为%d % (msg,os.getpid() # random.random()随机生成01之间的浮点数 time.

20、sleep(random.random()*2) t_stop = time.time() print(msg,执行完毕,耗时%0.2f % (t_stop-t_start)po = Pool(3) # 定义一个进程池,最大进程数3for i in range(0,10): # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,) # 每次循环将会用空闲出来的子进程去调用目标 po.apply_async(worker,(i,)print(-start-)po.close() # 关闭进程池,关闭后po不再接收新的请求po.join() # 等待po中所有子进程执行完

21、成,必须放在close语句之后print(-end-)运行效果:-start-0开始执行,进程号为214661开始执行,进程号为214682开始执行,进程号为214670 执行完毕,耗时1.013开始执行,进程号为214662 执行完毕,耗时1.244开始执行,进程号为214673 执行完毕,耗时0.565开始执行,进程号为214661 执行完毕,耗时1.686开始执行,进程号为214684 执行完毕,耗时0.677开始执行,进程号为214675 执行完毕,耗时0.838开始执行,进程号为214666 执行完毕,耗时0.759开始执行,进程号为214687 执行完毕,耗时1.038 执行完毕,

22、耗时1.059 执行完毕,耗时1.69-end-multiprocessing.Pool常用函数解析:apply_async(func, args, kwds) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;close():关闭Pool,使其不再接受新的任务;terminate():不管任务是否完成,立即终止;join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;进程池中的Queue如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:RuntimeError: Queue objects should only be shared between processes through inheritance.下面的实例演示了进程池中的进程如何通信:# 修改import中的Queue为Managerfrom multiprocessing import Manager, Poolimport os, time, randomd

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论