【python自动化第十篇:】
复习:
线程与进程的区别:
进程:资源的集合
线程:最小调度单位
- 进程至少包含一个线程
-
- 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁,join(等待线程执行完成)
信号量:也相当于是lock
守护线程:服务于非守护线程;
quene:程序的解耦;提高效率;也是有序的容器;队列只有一份数据,取完了就没有了
先进先出(FIFO)
后进先出(LIFO)
生产者消费者模型:也就是为了实现解耦
event:事件---红绿灯实验
i/o不占用cpu,计算占用
python多线程不适合cpu密集型操作任务,适合i/o密集型任务
推荐的书:
《失控》,《必然》
《数学之美》,《浪潮之巅》
鸡汤总结:做一个有素质的人
本章内容:
- govent协程
- select\poll\epoll异步I/O事件驱动
- python连接mysql的基本操作
- rabbitmq队列
- redis/memcached缓存
- paramiko ssh
- twisted网络框架
一、多进程
解决多核问题而生
单个进程:
1
2
3
4
5
6
7
8
9
10
|
#!/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() #进程等待 |
多进程:
1
2
3
4
5
6
7
8
9
10
11
|
#!/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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/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 ( '\n\n' ) def f(name): #定义功能函数 info( '\033[31;1mfunction f\033[0m' ) print ( 'hello' ,name) if __name__ = = '__main__' : #主进程调用 info( '\033[32;1mmain process line\033[0m' ) p = multiprocessing.Process(target = f,args = ( 'hehe' ,)) #定义进程 p.start() #开始进程 p.join() #进程等待 |
每一个子进程都是有其父进程启动的
进程间通信:Queue
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/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:实现进程间数据共享
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/usr/bin/env python # -*- coding:utf-8 -*- 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) |
结果如下:
1
2
3
4
5
6
7
8
|
D:\pythom35\python.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 ] |
进程锁:实现进程同步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/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() #启动进程 |
进程池:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/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() |
二、协程
又名微线程,轻量级线程;
协程拥有自己的寄存器上下文和栈;协程