python---进程与线程(四)---process类,进程间通信,进程池,协程

 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:进程号。

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只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。
       通过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)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值