zoukankan      html  css  js  c++  java
  • python学习第三十二节(进程间通信、进程池、协程)

    当多线程创建完毕之后,start并没有了立刻运行,依旧需要和其他线程抢CPU的资格,只是
    时间很短。
    进程之间的通信分为两种,queue和pipe

     1 import multiprocessing
     2 def foo(q):
     3     q.put([1,'hello',True])
     4 if __name__=='__main__':
     5     q=multiprocessing.Queue()#通过multiprocessing建立一个队列
     6     p=multiprocessing.Process(target=foo,args=(q,))
     7   #用multiprocessing在调用Process,建立一个子进程,定义函数名,将q作为参数传到foo函数,
     8     #foo函数就可以通过这个参数来与主进程做交互了。
     9     p.start()#激活这个子进程
    10     print(q.get())#主进程

    上面函数通过multiprocessing的queue来实现进程间通信。

     1 from multiprocessing import  Pipe,Process
     2 def foo(sk):
     3     sk.send('hello world')#通过管道sk发送内容
     4     print(sk.recv())#打印接收到的内容
     5 if __name__ == '__main__':
     6     sock,conn=Pipe()#定义一个管道的两头
     7     p=Process(target=foo,args=(sock,))#由于上面已经通过multiprocessing导入了Process,
     8     # 所以这里直接就可以创建一个子进程,并将sock(管道的一头)作为参数给foo函数
     9     p.start()#激活这个进程
    10     print(conn.recv())#打印接收到的内容,conn是管道的另一头
    11     conn.send('hi son')#通过管道发送内容

    上面代码通过Pipe来实现两个进程间的通信。

     1 from multiprocessing import  Manager,Process
     2 def foo(l,i):#收到参数,l是Mlist,i是循环的i
     3     l.append(i*i)#将i平方添加到Mlist
     4 if __name__=='__main__':
     5     manager=Manager()
     6     Mlist=manager.list([11,22,33])#定义一个列表
     7 
     8     l=[]
     9     for i in range(5):#创建5个子进程
    10         p=Process(target=foo,args=(Mlist,i))#定义一个进程,将Mlist和i作为参数传到foo
    11         p.start()#激活这个进程,执行foo函数
    12         l.append(p)#将5个进程添加到l这个列表
    13     for i in l:
    14         i.join()#循环这个列表,然后将每个进程join
    15     print(Mlist)#当所有的子进程都结束,运行主进程

    上面代码通过Manger实现子进程间的通信。

    协程
    协程,又叫微线程,实际上就是单线程,通过python语法,或模块来实现并发。
    本质上就是一个进程一个线程。

    上图是用yield实现了一个两个函数逇并发处理。

     1 from greenlet import greenlet#导入这个模块
     2 def foo():#定义一个函数
     3     print('ok1')#打印
     4     gr2.switch()#将程序切换到下面一个函数,按照名字切
     5     print('ok3')#打印
     6     gr2.switch()#将程序切换到下面一个函数,按照名字切
     7 def bar():
     8     print('ok2')#打印
     9     gr1.switch()#切到上面foo函数
    10     print('ok4')
    11 gr1=greenlet(foo)#实例化这个函数
    12 gr2=greenlet(bar)
    13 gr1.switch()#在外面写这个就执行了这个函数

    通过greenlet模块的switch来实现协程的切换,greenlet模块需要手动去pycharm下载

     1 import gevent#导入这个模块
     2 def foo():
     3     print('running in foo')
     4     gevent.sleep(2)#打印之后睡一秒,模拟io操作
     5     print('switch to foo again')
     6 def bar():
     7     print('switch  to bar')
     8     gevent.sleep(1)#打印之后睡一秒,模拟io操作
     9     print('switch to bar again')
    10 gevent.joinall([gevent.spawn(foo),gevent.spawn(bar)])
    11 '''
    12 这个程序的运行过程是,先执行foo函数,
    13 打印之后遇到了IO操作,然后自动切换到下一个函数执行,
    14 打印之后又遇到了IO操作,然后切回foo函数发现IO2秒还没有结束,
    15 然后又切到了bar函数发现IO结束,打印,再切回foo函数打印
    16 '''

    上面代码通过gevent模块来实现写成的IO期间自动切换实现并发的程序。
    gevent需要从pycharm下载。

  • 相关阅读:
    javascript实现网页分享至朋友圈功能
    Vue中全局过滤器期与局部过滤器期的使用
    vue中添加与删除,关键字搜索
    vue生命周期
    4种常用的Ajax请求方式
    CSS 基础总结
    BEM思想之彻底弄清BEM语法
    学习前端过程中用到的资料
    深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.
    html基础
  • 原文地址:https://www.cnblogs.com/ArmoredTitan/p/7212171.html
Copyright © 2011-2022 走看看