python---进程与线程(四)---process类,进程间通信,进程池,协程
2017-07-20 15:45
363 查看
Process([group [, target [, name [, args [, kwargs]]]]])
group: 线程组,目前还没有实现,库引用中提示必须是None;
target: 要执行的方法;
name: 进程名;
args/kwargs: 要传入方法的参数。
实例方法:
is_alive():返回进程是否在运行。
join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
start():进程准备就绪,等待CPU调度
run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
terminate():不管任务是否完成,立即停止工作进程
属性:
daemon:和线程的setDeamon功能一样
name:进程名字。
pid:进程号。
=================================================================
进程队列Queue
Pipe()
Pipe的本质是进程之间的数据传递,而不是数据共享,这和socket有点像。pipe()返回两个连接对象分别表示管道的两端,每端都有send()和recv()方法。如果两个进程试图在同一时间的同一端进行读取和写入那么,这可能会损坏管道中的数据。
=================================================================
Manager
Queue和pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。
4000
通过Manager可实现进程间数据的共享。Manager()返回的manager对象会通过一个服务进程,来使其他进程通过代理的方式操作python对象。manager对象支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value ,Array.
=================================================================
进程池
由于进程启动的开销比较大,使用多进程的时候会导致大量内存空间被消耗。为了防止这种情况发生可以使用进程池,(由于启动线程的开销比较小,所以不需要线程池这种概念,多线程只会频繁得切换cpu导致系统变慢,并不会占用过多的内存空间)
进程池中常用方法:
apply() 同步执行(串行)
apply_async() 异步执行(并行)
terminate() 立刻关闭进程池
close() 等待所有进程结束后,才关闭进程池。
join() 主进程等待所有子进程执行完毕。必须在close或terminate()之后。
=================================================================
协程
协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
yield实现协程
greenlet模块
greenlet机制的主要思想是:生成器函数或者协程函数中的yield语句挂起函数的执行,直到稍后使用next()或send()操作进行恢复为止。可以使用一个调度器循环在一组生成器函数之间协作多个任务。greentlet是python中实现我们所谓的"Coroutine(协程)"的一个基础库.
Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成。
# import re,requests,time,gevent
# def foo(url):
#
# response=requests.get(url)
# response_str=response.text
# return response_str
#
# def bar(url):
# res=foo(url)
# obj=re.compile('<img src="(.*?)" width="251" height="360" title=".*?" alt=".*?">',re.S)
# lis = obj.findall(res)
# print(lis)
# if __name__ == '__main__':
# s=time.time()
# gevent.joinall([gevent.spawn(bar,'http://www.youwu.cc/tag/boluoshe/list_1.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_2.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_3.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_4.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_5.html')])
# print(time.time()-s)
group: 线程组,目前还没有实现,库引用中提示必须是None;
target: 要执行的方法;
name: 进程名;
args/kwargs: 要传入方法的参数。
实例方法:
is_alive():返回进程是否在运行。
join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
start():进程准备就绪,等待CPU调度
run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
terminate():不管任务是否完成,立即停止工作进程
属性:
daemon:和线程的setDeamon功能一样
name:进程名字。
pid:进程号。
import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self): super().__init__() def run(self): print('{} say ok'.format(self.name)) if __name__ == '__main__': p=MyProcess() p.start()
=================================================================
进程队列Queue
# import multiprocessing # # def foo(q): # q.put('ds') # # # q = multiprocessing.Queue() # if __name__ == '__main__': # # p=multiprocessing.Process(target=foo,args=(q,)) # p.start() # print(q.get())=================================================================
Pipe()
Pipe的本质是进程之间的数据传递,而不是数据共享,这和socket有点像。pipe()返回两个连接对象分别表示管道的两端,每端都有send()和recv()方法。如果两个进程试图在同一时间的同一端进行读取和写入那么,这可能会损坏管道中的数据。
# from multiprocessing import Pipe,Process # # def foo(conn): # conn.send('dw') # print(conn.recv()) # # # if __name__ == '__main__': # sock, conn = Pipe() # q=Process(target=foo,args=(conn,)) # q.start() # # print(sock.recv()) # sock.send('dd')
=================================================================
Manager
Queue和pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。
4000
通过Manager可实现进程间数据的共享。Manager()返回的manager对象会通过一个服务进程,来使其他进程通过代理的方式操作python对象。manager对象支持 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value ,Array.
# from multiprocessing import Manager,Process # # def foo(d,x,y): # d[x]=y # if __name__ == '__main__': # manager=Manager() # Mdict=manager.dict({'kill':9572}) # l=[] # for i in range(5): # p=Process(target=foo,args=(Mdict,'dog{}'.format(i),i)) # p.start() # l.append(p) # for j in l : # j.join() # # print(Mdict)
=================================================================
进程池
由于进程启动的开销比较大,使用多进程的时候会导致大量内存空间被消耗。为了防止这种情况发生可以使用进程池,(由于启动线程的开销比较小,所以不需要线程池这种概念,多线程只会频繁得切换cpu导致系统变慢,并不会占用过多的内存空间)
进程池中常用方法:
apply() 同步执行(串行)
apply_async() 异步执行(并行)
terminate() 立刻关闭进程池
close() 等待所有进程结束后,才关闭进程池。
join() 主进程等待所有子进程执行完毕。必须在close或terminate()之后。
# from multiprocessing import Pool # import time # # def foo(n): # print(n) # time.sleep(1) # if __name__ == '__main__': # pool_obj=Pool(5)#进程池内有5个进程 # # for i in range(100):#开100任务 # p=pool_obj.apply_async(func=foo,args=(i,)) # # print(p,type(p)) # print(pool_obj,type(pool_obj)) # pool_obj.close() # pool_obj.join()
=================================================================
协程
协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
yield实现协程
# import time # # def consumer(): # r = '' # while True: # n = yield r # print('消费%s'%n) # time.sleep(1) # r='200 ok' # # def produce(c): # next(c) # n = 0 # while n<5: # n+=1 # print('生产%s'%n) # cr = c.send(n) # # print('消费反馈%s'%cr) # c.close() # # if __name__ == '__main__': # c=consumer() # produce(c)-------------------------------------------------------------------------------------------------------------------
greenlet模块
greenlet机制的主要思想是:生成器函数或者协程函数中的yield语句挂起函数的执行,直到稍后使用next()或send()操作进行恢复为止。可以使用一个调度器循环在一组生成器函数之间协作多个任务。greentlet是python中实现我们所谓的"Coroutine(协程)"的一个基础库.
import greenlet def foo(): print(1) b.switch() print(3) b.switch() def bar(): print(2) f.switch() print(4) f=greenlet.greenlet(foo) b=greenlet.greenlet(bar) f.switch()-------------------------------------------------------------------------------------------------------------------
Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成。
# import re,requests,time,gevent
# def foo(url):
#
# response=requests.get(url)
# response_str=response.text
# return response_str
#
# def bar(url):
# res=foo(url)
# obj=re.compile('<img src="(.*?)" width="251" height="360" title=".*?" alt=".*?">',re.S)
# lis = obj.findall(res)
# print(lis)
# if __name__ == '__main__':
# s=time.time()
# gevent.joinall([gevent.spawn(bar,'http://www.youwu.cc/tag/boluoshe/list_1.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_2.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_3.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_4.html'),
# gevent.spawn(bar, 'http://www.youwu.cc/tag/boluoshe/list_5.html')])
# print(time.time()-s)
相关文章推荐
- Python基础学习(5)网络编程socket、文件上传、粘包问题、socketserver、IO多路复用、线程与进程、进程池、线程池、上下文管理、协程
- python多进程笔记4 - 进程间通信总结,Python中线程存在的问题
- python 创建:udp tcp服务器 线程 进程 进程池 互斥锁 协程
- Python--线程队列(queue)、multiprocessing模块(进程对列Queue、管道(pipe)、进程池)、协程
- Python线程、进程、进程池、协程
- Python进程、进程池以及进程间通信
- Python中并发、进程、线程的总结
- Python进阶(4)_进程与线程 (python并发编程之多进程)
- python多进程、进程间通信、进程锁
- python笔记六:进程与线程
- python 学习笔记7进程和线程
- Linux进程线程初探(多进程与进程间通信-管道)
- python学习笔记-------进程,进程锁,进程间通信,进程的同步异步
- 【Python】进程线程协程对比
- Python学习第二十天——线程、进程与赛车游戏
- python/进程线程的总结
- python线程与进程手记
- Python下进程与线程的原理及区别
- 人生苦短之我用Python篇(线程/进程、threading模块:全局解释器锁gil/信号量/Event、)
- python threading父进程不死,子线程不退出..如何才能使用完线程后回收线程?