复习:
线程与进程的区别:
进程:资源的集合
线程:最小调度单位
- 进程至少包含一个线程
-
- 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁,join(等待线程执行完成)
信号量:也相当于是lock
守护线程:服务于非守护线程;
quene:程序的解耦;提高效率;也是有序的容器;队列只有一份数据,取完了就没有了
先进先出(FIFO)
后进先出(LIFO)
生产者消费者模型:也就是为了实现解耦
event:事件---红绿灯实验
i/o不占用cpu,计算占用
python多线程不适合cpu密集型操作任务,适合i/o密集型任务
推荐的书:
《失控》,《必然》
《数学之美》,《浪潮之巅》
鸡汤总结:做一个有素质的人
今天的课程:
- govent协程
- selectpollepoll异步I/O事件驱动
- python连接mysql的基本操作
- rabbitmq队列
- redis/memcached缓存
- paramiko ssh
- twisted网络框架
一、多进程
解决多核问题而生
单个进程:
#!/usr/bin/env python # -*- coding:utf-8 -*- import multiprocessing,time def run(name): #定义函数 time.sleep(1) print('hello',name) if __name__ == '__main__': p = multiprocessing.Process(target=run,args=('hehe',)) #实例化一个进程 p.start() #执行进程 p.join() #进程等待
多进程:
#!/usr/bin/env python # -*- coding:utf-8 -*- import multiprocessing,time def run(name): print('hello',name) time.sleep(1) if __name__ == '__main__': for i in range(10): #定义循环 p = multiprocessing.Process(target=run,args=("hehe %s"%i,)) p.start()
获取进程id:
#!/usr/bin/env python # -*- coding:utf-8 -*- import multiprocessing,os def info(title): #信息展示函数 print(title) print('module name:',__name__) #打印模块名称 print('parent process id',os.getppid()) #父进程id获取 print('process id',os.getpid()) #当前进程id print(' ') def f(name): #定义功能函数 info(' 33[31;1mfunction f 33[0m') print('hello',name) if __name__ == '__main__': #主进程调用 info(' 33[32;1mmain process line 33[0m') p = multiprocessing.Process(target=f,args=('hehe',)) #定义进程 p.start() #开始进程 p.join() #进程等待
每一个子进程都是有其父进程启动的
进程间通信:Queue
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Queue,Process def f(qq): qq.put([122,None,'heheheda']) #父进程放入数据 if __name__ == '__main__': q = Queue() p = Process(target=f,args=(q,)) #将q传给子进程p p.start() print(q.get()) p.join()
此时的q也就是pickle序列化和 反序列化之后的结果了,实现了进程间的通信
管道pipe:
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process,Pipe def f(conn): conn.send([123,'sada',None]) #子进程send数据 conn.send([12223,'s343ada321',None]) #子进程send数据 print(conn.recv()) #子进程接受父进程数据 conn.close() if __name__ == '__main__': parent_conn,chile_conn = Pipe() #生成一个管道实例 p = Process(target=f,args=(chile_conn,)) #实例化 p.start() print(parent_conn.recv()) #父进程接收数据 print(parent_conn.recv()) #父进程接收数据 # print(parent_conn.recv()) #父进程接收数据,如果子进程不发送数据,父进程就处于等待状态 parent_conn.send('hello child!!') #父进程给子进程发送数据 p.join()
mananger:实现进程间数据共享
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui from multiprocessing import Manager,Process import os def f(d,l): d[os.getpid()] = os.getpid() #获取pid l.append(os.getpid()) print(l) if __name__ == '__main__': with Manager() as manager: d = manager.dict() #生成一个字典,可在多个进程间共享和传递 l = manager.list(range(5)) #生成一个列表,可在多个进程间共享和传递数据 p_list = [] for i in range(5): p = Process(target=f,args=(d,l)) p.start() p_list.append(p) for res in p_list: #等待结果 res.join() print(d) print(l)
结果如下:
D:pythom35python.exe D:/project/s14/day10/manager2.py [0, 1, 2, 3, 4, 7828] [0, 1, 2, 3, 4, 7828, 4180] [0, 1, 2, 3, 4, 7828, 4180, 1800] [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076] [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076, 7264] {1800: 1800, 4180: 4180, 8076: 8076, 7828: 7828, 7264: 7264} #进程字典打印结果 [0, 1, 2, 3, 4, 7828, 4180, 1800, 8076, 7264]
进程锁:实现进程同步
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process,Lock def f(l,i): ''' :param l: 锁 :param i: 传进来的内容 :return: ''' # l.acquire() print('hehehe',i) #l.release() if __name__ == '__main__': lock = Lock() for num in range(100): #修改进程的启动数量 Process(target=f,args=(lock,num)).start() #启动进程
进程池:
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Process,Pool import time,os def Foo(i): time.sleep(1) print('in process',os.getpid()) return i + 100 def Bar(arg): print("-->exec done",arg,os.getpid()) #获取子进程pid if __name__ == '__main__': pool = Pool(5) #允许进程池里同时放入5个进程 print('主进程',os.getpid()) #获取主进程pid for i in range(10): #启动10个进程 pool.apply_async(func=Foo,args=(i,),callback=Bar) #异步执行(并行),需要执行join ,callback:回调 #pool.apply(func=Foo,args=(i,)) #将Foo放入进程池,串行 print('end') pool.close() pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()
二、协程
又名微线程,轻量级线程;
协程拥有自己的寄存器上下文和栈;协程