【python自动化第十篇:】

复习:

  线程与进程的区别:

    进程:资源的集合

    线程:最小调度单位

  • 进程至少包含一个线程
    • 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁,join(等待线程执行完成)

           信号量:也相当于是lock

    守护线程:服务于非守护线程;

    quene:程序的解耦;提高效率;也是有序的容器;队列只有一份数据,取完了就没有了

        先进先出(FIFO)

        后进先出(LIFO)

    生产者消费者模型:也就是为了实现解耦

    event:事件---红绿灯实验

i/o不占用cpu,计算占用

python多线程不适合cpu密集型操作任务,适合i/o密集型任务

推荐的书:

  《失控》,《必然》

  《数学之美》,《浪潮之巅》

鸡汤总结:做一个有素质的人

今天的课程:

  1. govent协程
  2. select\poll\epoll异步I/O事件驱动
  3. python连接mysql的基本操作
  4. rabbitmq队列
  5. redis/memcached缓存
  6. paramiko ssh
  7. 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('\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

#!/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:\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]

进程锁:实现进程同步

#!/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()

二、协程

  又名微线程,轻量级线程;

  协程拥有自己的寄存器上下文和栈;协程

  

 

 

 

 

 

 

    

posted @ 2016-09-26 19:10  valiente  阅读(1089)  评论(0编辑  收藏  举报