当多线程创建完毕之后,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下载。